ZYBZYB has a tree with NN nodes,now he wants you to solve the numbers of nodes distanced no more than KK for each node. the distance between two nodes(x,y)(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 AA and BB,let fa_ifai be the father of node ii,fa_1=0fa1=0,fa_i=(A*i+B)\%(i-1)+1fai=(A∗i+B)%(i−1)+1 for i \in [2,N]i∈[2,N] .
For printing:let ans_iansi be the answer of node ii,you only need to print the xorxor sumsum of all ans_iansi.
In the first line there is the number of testcases TT.
For each teatcase:
In the first line there are four numbers NN,KK,AA,BB
1 \leq T \leq 51≤T≤5,1 \leq N \leq 5000001≤N≤500000,1 \leq K \leq 101≤K≤10,1 \leq A,B \leq 10000001≤A,B≤1000000
For TT lines,each line print the ans.
Please open the stack by yourself.
N \geq 100000N≥100000 are only for two tests finally.
1 3 1 1 1
3
树形dp
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 5 * 1e5 + 10;
int T, n, K, A, B, fa[maxn];
int dp[maxn][11];
int find(int x)
{
int ans = 0, sum[11] = {0};
for (int i = 0, j = x, k = 0; j && i <= K; i++)
{
sum[i] += 1;
for (int u = 1; u <= K - i; u++)
{
sum[u + i] += dp[j][u] - dp[k][u - 1];
}
k = j;
j = fa[j];
}
for (int i = 0; i <= K; i++) ans += sum[i];
return ans;
}
int main()
{
scanf("%d", &T);
while (T--)
{
memset(dp, 0, sizeof(dp));
scanf("%d%d%d%d", &n, &K, &A, &B);
fa[1] = 0;
for (int i = 2; i <= n; i++)
{
fa[i] = ((LL)A*i + B) % (i - 1) + 1;
for (int j = i, k = 0; j&&k <= K; j = fa[j], k++) dp[j][k]++;
}
int ans = 0;
for (int i = 1; i <= n; i++) ans ^= find(i);
printf("%d\n", ans);
}
return 0;
}