XXX is puzzled with the question below:
1, 2, 3, ..., n (1<=n<=400000) are placed in a line. There are m (1<=m<=1000) operations of two kinds.
Operation 1: among the x-th number to the y-th number (inclusive), get the sum of the numbers which are co-prime with p( 1 <=p <= 400000).
Operation 2: change the x-th number to c( 1 <=c <= 400000).
For each operation, XXX will spend a lot of time to treat it. So he wants to ask you to help him.
容斥原理
1 #include<stdio.h>
2 #include<string.h>
3 #include<algorithm>
4 #include<math.h>
5 using namespace std;
6 typedef long long ll;
7
8 const int maxn=4e5+5;
9
10 inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
11
12 int ori[1005],cha[1005];
13 int pnum[50],num;
14
15 int main(){
16 int T;
17 scanf("%d",&T);
18 while(T--){
19 int n,m;
20 scanf("%d%d",&n,&m);
21 int cnt=0;
22 while(m--){
23 int f;
24 scanf("%d",&f);
25 if(f==1){
26 int x,y,p;
27 scanf("%d%d%d",&x,&y,&p);
28 int tmp=p;
29 num=0;
30 for(int i=2;i*i<=tmp;++i){
31 if(!(tmp%i)){
32 pnum[++num]=i;
33 tmp/=i;
34 while(!(tmp%i))tmp/=i;
35 }
36 }
37 if(tmp>1)pnum[++num]=tmp;
38 ll ans=0;
39 for(int i=1;i<(1<<num);++i){
40 int bit=0;
41 ll mul=1;
42 for(int j=1;j<=num;++j){
43 if(i&(1<<(j-1))){
44 bit++;
45 mul*=pnum[j];
46 }
47 }
48 ll tmp=y/mul-(x-1)/mul;
49 ll l=((x-1)/mul+1)*mul,r=y/mul*mul;
50 tmp=(l+r)*tmp/2;
51 if(bit%2)ans+=tmp;
52 else ans-=tmp;
53 }
54 ans=(x+y)*(ll)(y-x+1)/2-ans;
55 for(int i=1;i<=cnt;++i){
56 if(ori[i]>=x&&ori[i]<=y){
57 int gcd1=gcd(ori[i],p),gcd2=gcd(cha[i],p);
58 if(gcd1==1&&gcd2>1)ans-=ori[i];
59 else if(gcd1>1&&gcd2==1)ans+=cha[i];
60 else if(gcd1==1&&gcd2==1)ans=ans-ori[i]+cha[i];
61 }
62 }
63 printf("%lld
",ans);
64 }
65 else{
66 int x,c;
67 scanf("%d%d",&x,&c);
68 bool f=1;
69 for(int i=1;i<=cnt;++i){
70 if(ori[i]==x){
71 cha[i]=c;
72 f=0;
73 break;
74 }
75 }
76 if(f){
77 ++cnt;
78 ori[cnt]=x;
79 cha[cnt]=c;
80 }
81 }
82 }
83 }
84 return 0;
85 }