题意:求有几组满足 a+b^2-c^3=0(mod k) 1<=a<=b<=c<=n (a,b,c)。
思路:树状数组
注意到 当b固定时 考虑a 1~b%k有b/k+1 b%k+1~k 有b/k个
从大至小枚举b,每次tree[b^3%k]++ 查询 (1+b*b)%k~(b%k+b*b)%k 总和sum*(b/k+1)+(sum总-sum)*b/k
1 #include<iostream>
2 #include<cstdio>
3 #include<cmath>
4 #include<cstring>
5 using namespace std;
6 #define NMAX 100001
7 int n,k;
8 int tree[NMAX];
9 long long ans;
10 int lowbit(int x)
11 {
12 return x&(x^(x-1));
13 }
14 void update(int i)
15 {
16 while(i<=k)
17 {
18 tree[i]++;
19 i+=lowbit(i);
20 }
21 }
22 int sum(int i)
23 {
24 int ret=0;
25 while(i>0)
26 {
27 ret+=tree[i];
28 i-=lowbit(i);
29 }
30 return ret;
31 }
32 void add(int Min,int Max,int t)
33 {
34 long long ret=0;
35 if(Min<Max) ret=sum(Max)-sum(Min);
36 else ret=sum(k)-sum(Min)+sum(Max);
37 ans+=t*ret+(t-1)*(sum(k)-ret);
38 }
39 int main()
40 {
41 int T;
42 int i,j;
43 int b;
44 int Min,Max;
45 int temp;
46
47 scanf("%d",&T);
48 for(j=1;j<=T;j++)
49 {
50 ans=0;
51 memset(tree,0,sizeof(tree));
52 scanf("%d%d",&n,&k);
53 for(b=n;b>0;b--)
54 {
55 temp=((long long)b*b*b-1)%k+1;
56 update(temp);
57 temp=((long long)b*b-1)%k+1;
58 Max=(b%k+temp+k-1)%k+1;
59 Min=temp%k;
60 add(Min,Max,(b-1)/k+1);
61 }
62 printf("Case %d: %lld\n",j,ans);
63 }
64 return 0;
65 }
66
67