T1 高一学堂
高一学堂,因为有了yxryxryxr,就成了现在这个样子 = =。由于yxryxryxr 的语言太过雷人,每次他发微往往都会有一石激起千层浪的效果,具体就是所有关注他的人都会转发,同时@@@他,接着关注这些人的人也会转发,同时@@@他关注的人(注意转发内容本身会有@@@yxryxryxr),以此类推。这样导致每次yxryxryxr 发微博都会被@@@上兆次,而yxryxryxr 又特别喜欢发,sina 支持不了如此庞大的数据量,特出规定,每次转发时,@@@的人不能超过K 人,好友在转发时如果超过了,就把最早那人删掉。现在yxryxryxr 刚发了一条微博“求满分”,他想知道每个与他有联系的人分别会被@@@多少次。
输入格式:
输入第一行有三个整数,NNN,KKK,表示人数和KKK。
接下来 N−1N-1N−1 行,每行有2 个整数 aaa,bbb,表示 aaa 和 bbb 有关注关系。
输入给出一棵以 111 号点为根的树,一号点代表 yxryxryxr,对于任意一个点,他的儿子都关注他。
输出格式:
输出有 NNN 行,每行有一个整数,这个人会被 @@@ 多少次。
样例输入:
5 2
1 2
2 3
2 4
4 5
样例输出:
3
3
0
1
0
数据范围:
对于30%30\%30%的数据,NNN ≤100;
对于60%60\%60%的数据,NNN ≤2000,KKK ≤100;
对于100%100\%100%的数据,NNN ≤100000, KKK ≤ NNN。
题解:
- 其实就是求每个结点深度差不超过 KKK 的儿子个数
- 每个结点的儿子个数 - 它 k+1k+1k+1 层每个儿子的儿子个数
#include <bits/stdc++.h>
using namespace std;
vector<int> a[100010];
vector<int> b[100010];
int d[100010],h[100010],k;
void dfs(int u,int fa,int dep)
{
d[u]=dep;
for(int i=0; i<a[u].size(); i++)
{
int v=a[u][i];
if(v==fa) continue;
dfs(v,u,dep+1);
h[u]+=h[v]+1;
}
}
void dfs_2(int u,int fa,int dep)
{
b[d[u]].push_back(u); // 当前子树下,此深度的结点
if(b[dep-k-1].size()&&dep-k-1>0) // 减掉它k+1儿子结点的儿子个数
{
for(int i=0; i<b[dep-k-1].size(); i++)
{
int v=b[dep-1-k][i];
h[v]=h[v]-h[u]-1;
}
}
for(int i=0; i<a[u].size(); i++)
{
int v=a[u][i];
if(v==fa) continue;
dfs_2(v,u,dep+1);
}
// 回溯时把当前结点删除
vector<int>::iterator it;
for(it=b[d[u]].begin();it!=b[d[u]].end();it++)
if(*it==u)
{
b[d[u]].erase(it);
break;
}
}
int main()
{
int n,i,x,y;
scanf("%d%d",&n,&k);
for(i=1; i<n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[x].push_back(y);
a[y].push_back(x);
}
dfs(1,0,1); // 记录深度和儿子结点的个数
dfs_2(1,0,1);
for(i=1; i<=n; i++) printf("%d\n",h[i]);
return 0;
}
T2 高二学堂
Wayne 有一副加强版的扑克牌,强大到任意取一个自然数x,在牌堆里都恰
有 444 张数值为 xxx 的牌。每次,Wayne 随机生成两个正整数 nnn 和k,然后在牌堆里选取不超过 kkk 张牌,使得牌面数字之和恰为 nnn。已知Wayne 玩了若干盘,每盘都算出了对应的方案数,他想请你也算出各盘方案数,以验算他的结果是否正确。结果可能比较大,你只需要求出方案数modmodmod 1000000009(1e9+9) 的值即可。
输入格式:
输入文件包含不超过101010 组数据。
每行包含两个整数,表示上文中的 nnn 和 kkk。
输入数据以两个000 表示结束。
输出格式:
输出文件中,每组数据输出一行,为对应的方案数。
样例输入:
2 1
2 2
2 3
50 5
0 0
样例输出:
4
10
10
1823966
数据范围:
对于 10%10\%10%的数据,kkk=1;
对于 20%20\%20%的数据,nnn ≤10,kkk ≤4;
对于 40%40\%40%的数据,nnn ≤1000;
对于 60%60\%60%的数据,nnn ≤100000;
对于另外 20%20\%20% 的数据,只有 111 组数据;
对于 100%100\%100%的数据,nnn ≤10^9,kkk ≤10。
题解
- 不好意思目前本蒟蒻只会404040分做法,等以后会100100100分了再回来更新(也许你等不到这一天)
- (题意)选取不超过 kkk 个数,每个数可以取至多444个,不考虑000,使得数字之和为 nnn
- dp[i][j]dp[ i ][ j ]dp[i][j] : 和为 iii ,取 jjj 个数的方案数
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
long long d[100010][12],c[10][10];
int main()
{
int n,k,i,j,l;
memset(d,0,sizeof(d));
c[4][1]=c[4][3]=4;
c[4][2]=6;
c[4][4]=1;
d[0][0]=1;
for(i=1; i<=1000; i++) // 当前正在取 i
for(j=10;j>=1;j--) // 取 j 个数
for(l=0; l<=1000; l++) // 和为 l
for(k=1; k<=min(4,j)&&k*i+l<=1000; k++) // i 取 k 个
d[k*i+l][j]=(d[k*i+l][j]+(d[l][j-k]*c[4][k])%mod)%mod;
while(scanf("%d%d",&n,&k)!=EOF)
{
if(!n&&!k) break;
long long s=0;
for(i=1; i<=k; i++) s=(s+d[n][i])%mod;
printf("%lld\n",s);
}
return 0;
}
T3 高三楼
一个 n∗nn * nn∗n 的矩阵,其中,每行每列都有两个特殊的点。
"重复"的定义为矩阵 aaa ,通过任意次行列变换,变成了矩阵 bbb,矩阵 aaa ,bbb就视为重复。
例如:对于 3∗33*33∗3 的矩阵,其中矩阵 aaa 与矩阵 bbb 被视为“重复”矩阵。
对于一个 nnn,可以有多少种不“重复”的矩阵,输出答案modmodmod100000007(1e8+7) 的值。
输入格式:
第一行,一个整数 ttt,表示数据组数。
接下来 ttt 行,每行一个整数 nnn,表示一组数据。
输出格式:
TTT 行,每行一个整数,表示方案数。由于答案可能很大,只需要输出方案数
mod100,000,007mod 100,000,007mod100,000,007 的值就可以了。
样例输入:
3
2
3
4
样例输出:
1
1
2
数据范围:
对于10%10\%10%的数据 NNN ≤ 555;
对于50%50\%50%的数据 NNN ≤ 150150150;
对于100%100\%100%的数据 TTT ≤555 , NNN ≤ 200020002000
题解
- 此题解法神奇,因为每行每列只有两个标记,所以我们可以把行和列,想成一个二分图的两条边
- 两条边之间的连线等价于某一个标记
- 两条边上的点的移动等价于标记的行列变换
- 所以我们只要考虑有多少种不同的连法即可
- e.g. (可以手模以下 n=5n = 5n=5)
- 然后——惊奇地发现(๑╹◡╹)ノ(๑╹◡╹)ノ(๑╹◡╹)ノ 每 2∗x(1<x<=n)2*x(1 < x <= n)2∗x(1<x<=n)点就会构成一个环
- 每种环的组成,代表一种方案,排列并不重要
- So—— n=a1+a2+......+amn = a_1+a_2+......+a_mn=a1+a2+......+am (am>1)(a_m > 1)(am>1)
- 于是就转化成了正整数拆分的问题︿( ̄︶ ̄)︿︿( ̄︶ ̄)︿︿( ̄︶ ̄)︿
#include <bits/stdc++.h>
using namespace std;
const int mod=1e8+7;
int d[100010];
int main()
{
int i,j;
memset(d,0,sizeof(d));
d[0]=1;
for(i=2;i<=2000;i++)
for(j=i;j<=2000;j++) d[j]=(d[j]+d[j-i])%mod;
// j = i + ( j - i )
scanf("%d",&i);
while(i--)
{
scanf("%d",&j);
printf("%d\n",d[j]);
}
return 0;
}