ZYB's Tree

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 400    Accepted Submission(s): 114

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.
the distance between two nodes(x,y) is defined the number of edges on their shortest path in the tree.

To save the time of reading and printing,we use the following way:

For reading:we have two numbers A and B,let fai be the father of node i,fa1=0,fai=(A∗i+B)%(i−1)+1 for i∈[2,N] .

For printing:let ansi be the answer of node i,you only need to print the xor sum of all ansi.

 
Input
In the first line there is the number of testcases T.

For each teatcase:

In the first line there are four numbers N,K,A,B

1≤T≤5,1≤N≤500000,1≤K≤10,1≤A,B≤1000000

 
Output
For T lines,each line print the ans.

Please open the stack by yourself.

N≥100000 are only for two tests finally.

 
Sample Input
1
3 1 1 1
 
Sample Output
3
 
Source
 
 
 

题目大意:给你一棵无根树,定义了结点距离为任意结点对(i,j)在最短路径上的边的条数。让你求出每个结点的结点距离
小于等于K的结点个数,然后求异或值。
解题思路:我们的总体思路是,先任意定一个根,形成一棵有根树,对于任意的结点,我们可以从距离该结点为K的儿孙结点
和祖先结点两个方面去统计结点个数。我们定义dp[u][j]表示以某个结点u为根的子树中,距离小于等于j的结点个数。现在我们
已经解决了距离该结点为K的儿孙方面的个数,还有祖先方面的需要统计,那么我们可以从结点u向他的祖先结点走,会经过u的父亲
祖父,曾祖父...依次向上。向上走i层,该祖先结点表示为ff,第i-1 层的祖先结点表示为pff。

那么会增加dp[ff][K-i] - dp[pff][K-i-1]个结点。
另外:题中给的1结点的父亲结点0是不用参与运算的。当到达0结点时,可以跳出循环。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
const int maxn = 550000;
typedef long long LL;
int N,K,A,B;
int f[maxn], dp[maxn][20];
vector<int>G[maxn];
void dfs(int u,int fa){
for(int i = 0; i <= K; i++){ //初始化以u为子树的根,距离u为i时的结点个数为1
dp[u][i] = 1;
}
for(int i = 0; i < G[u].size(); i++){
int v = G[u][i];
if(v == fa) continue;
dfs(v,u);
for(int j = 0; j <= K; j++){ //统计u的所有子节点
dp[u][j+1] += dp[v][j];
}
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d",&N,&K,&A,&B);
for(int i = 0; i <= N+20; i++){
G[i].clear();
}
f[1] = 0;
for(int i = 2; i <= N; i++){
int ff = (int)(((LL)A*i+B)%((LL)i-1) + 1); //计算时会超int
f[i] = ff;
G[ff].push_back(i);
}
memset(dp,0,sizeof(dp));
dfs(1,0);
int ans = 0, tmp;
for(int u = 1; u <= N; u++){
tmp = dp[u][K]; //子孙方面个数
int ff = u; //初始化祖先结点
for(int i = 1; i <= K; i++){
if(i == K){
tmp += dp[f[ff]][K-i]; continue;
}
if(f[ff] == 0){ //已经到了0结点
break;
}
tmp += dp[f[ff]][K-i] - dp[ff][K-i-1]; //统计向上经过的满足条件的祖先会贡献多少个结点
ff = f[ff]; //向祖先走
}
ans ^= tmp; //求每个结点的异或和
}
printf("%d\n",ans);
}
return 0;
}
/* 55
15 3 3 8 */

  

 

最新文章

  1. 【BZOJ1503】[HAOI2007]反素数ant 搜索
  2. IOS的MVC和MVVM模式简明介绍
  3. 在 Cloud 9 中搭建和运行 Go
  4. .net学习之进程外Session的配置
  5. php常量的声明和使用
  6. PHP去除BOM头的方法
  7. Ov
  8. Wireshark基本介绍和学习TCP三次握手(转)
  9. Java 与无符号那些事儿
  10. android开发之路06(浅谈单例设计模式)
  11. H5-xhtml+css2-静态百度首页练习
  12. getJSON的用法
  13. 在Weex中定制自定义组件
  14. 开源纯C#工控网关+组态软件(九)定制Visual Studio
  15. SQLServer之创建存储过程
  16. Oracle中如何查询CLOB字段类型的内容
  17. Confluence 6 升级自定义的站点和空间仔细测试你的修改
  18. President&#39;s Path CodeForces - 416E (最短路,计数)
  19. JAVA-7NIO之Socket/ServerSocket Channel
  20. nginx配置虚拟路径下载文件(.apk)

热门文章

  1. SQL 分组后拼接字符串
  2. 最全PyCharm教程--for python
  3. Oracle中date转为timstam可以函数to_timestamp的方式来转化
  4. [Emacs] Org-mode下表格内中英文不对齐的解决方案
  5. addEntriesFromDictionary用法
  6. Hawk-and-Chicken 强连通
  7. requests模块demo
  8. P2723 丑数 Humble Numbers
  9. 【三支火把】--- shell脚本中变量的类型及作用域
  10. Tensorflow方法介绍