Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
#include <iostream> #include <stdio.h> #include <queue> #include <stdio.h> #include <string.h> #include <vector> #include <queue> #include <set> #include <algorithm> #include <map> #include <stack> #include <math.h> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std ; typedef long long LL ; const int M_P=1008 ; bool isprime[M_P+8] ; int prime[M_P] ,id ; void make_prime(){ id=0 ; memset(isprime,0,sizeof(isprime)) ; for(int i=2;i<=M_P;i++){ if(!isprime[i]) prime[++id]=i ; for(int j=1;j<=id&&i*prime[j]<=M_P;i++){ isprime[i*prime[j]]=1 ; if(i%prime[j]==0) break ; } } } int gcd(int x ,int y){ return y==0?x:gcd(y,x%y) ; } struct Change{ int id ; int num ; }; vector<Change>query ; inline LL Sum(LL N){ return N*(1+N)/2 ; } LL gao(int N ,int P){ vector<int>vec ; vec.clear() ; LL ans=0 ; LL M=P ; for(int i=1;i<=id&&prime[i]*prime[i]<=M;i++){ if(M%prime[i]==0){ vec.push_back(prime[i]) ; while(M%prime[i]==0) M/=prime[i] ; } if(M==1) break ; } if(M!=1) vec.push_back(M) ; int n=vec.size() ; for(int i=1;i<(1<<n);i++){ int now=0 ; int pri=1 ; for(int j=0;j<n;j++){ if(i&(1<<j)){ now++ ; pri*=vec[j] ; } } if(now&1) ans=ans+pri*Sum(N/pri) ; else ans=ans-pri*Sum(N/pri) ; } return Sum(N)-ans ; } map<int ,int>my_hash ; int main(){ make_prime() ; int L ,R ,P ,N ,M ,T ,kind; scanf("%d",&T) ; while(T--){ scanf("%d%d",&N,&M) ; query.clear() ; while(M--){ scanf("%d",&kind) ; if(kind==1){ scanf("%d%d%d",&L,&R,&P) ; if(L>R) swap(L ,R) ; LL ans=gao(R,P)-gao(L-1,P) ; my_hash.clear() ; for(int i=0;i<query.size();i++){ int ID=query[i].id ; int Num=query[i].num ; if(L<=ID&&ID<=R){ if(my_hash.find(ID)==my_hash.end()){ if(gcd(ID,P)==1) ans-=ID ; } else{ LL now_num = my_hash[ID] ; if(gcd(now_num,P)==1) ans-=now_num ; } if(gcd(Num,P)==1) ans+=Num ; my_hash[ID]=Num ; } } printf("%I64d\n",ans) ; } else{ Change now ; scanf("%d%d",&now.id,&now.num) ; query.push_back(now) ; } } } return 0 ; }