ZYB's TreeTime Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 787 Accepted Submission(s): 265 Problem Description ZYB has a tree with N nodes,now he wants you to solve the numbers of nodes distanced no more than K for each node. Input In the first line there is the number of testcases T . Output For T lines,each line print the ans. Sample Input 1 3 1 1 1
扫描二维码关注公众号,回复:
2894562 查看本文章
Sample Output 3 Source Recommend hujie | We have carefully selected several similar problems for you: 6437 6436 6435 6434 6433 |
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long
/*
题目大意:给定一棵树的生成计算方式,
对每个点,计算距离小于等于k的个数,
并且对每个点这样的权重相异或,得到的值就是答案。
对于每个点,很明显有两种方式,一种是往下走距离为k,
一种是往上走距离为k.
令dp[i][k][0]为i节点往下走距离为k的点数,
dp[i][k][1]为i节点往上走距离为k的点数,
首先预处理往下走的点数,
分析下往上走的状态:
dp[u][k][1]=dp[p][k-1][1]///继续往上走
+dp[p][k-1][0]///往兄弟子树走
-dp[u][k-2][0]///减去走过本身的路。
当然空间可以优化下,第二个dfs运算的顺序要倒过来即可。。
*/
const int maxn =5e5+5;
const int mod=1e9+7;
///0代表朝下走
///dp[u][k][0]=sigma dp[v][k-1][0],
///dp[u][k][1]=dp[p][k-1][1]+dp[p][k-1][0]-dp[u][k-2][0]
///链式前向星
struct node{int nxt,u;};
int head[maxn],tot=0;
node edge[maxn<<1];
void init()
{
memset(head,-1,sizeof(head));
tot=0;
}
void add(int x,int y)
{
edge[tot]=node{head[x],y};
head[x]=tot++;
}
ll dp[maxn][15][2];///dp数组
ll n,k,a,b;
void dfs1(int u,int pre)
{
dp[u][0][0]=dp[u][0][1]=1;
for(int i=head[u];~i;i=edge[i].nxt)
{
int v=edge[i].u;
if(v==pre) continue;
dfs1(v,u);
for(int i=1;i<=k;i++) dp[u][i][0]+=dp[v][i-1][0];
}
}
void dfs2(int u,int pre)
{
for(int i=head[u];~i;i=edge[i].nxt)
{
int v=edge[i].u;
if(v==pre) continue;
for(int i=k;i>=2;i--) dp[v][i][1]=dp[u][i-1][1]+dp[u][i-1][0]-dp[v][i-2][0];
dp[v][1][1]=dp[u][0][1];
dfs2(v,u);
}
}
int main()
{
int t;scanf("%d",&t);
while(t--)
{
init();
memset(dp,0,sizeof(dp));
scanf("%lld%lld%lld%lld",&n,&k,&a,&b);
for(int i=2;i<=n;i++)
{
ll tp=((ll)a*i+b)%(i-1)+1;
add(tp,i);
add(i,tp);
}
dfs1(1,-1);
dfs2(1,-1);
ll ans=0,tp=0;
for(int i=1;i<=n;i++,tp=0)
{
for(int j=0;j<=k;j++) tp=tp+dp[i][j][0]+dp[i][j][1];
ans^=(tp-1);
}
printf("%lld\n",ans);
}
return 0;
}