1 // HDU5634 Rikka with Phi 线段树 2 // 思路:操作1的时候,判断一下当前区间是不是每个数都相等,在每个数相等的区间上操作。相当于lazy,不必更新到底。 3 4 5 #include <bits/stdc++.h> 6 using namespace std; 7 #define clc(a,b) memset(a,b,sizeof(a)) 8 #define inf 0x3f3f3f3f 9 #define lson l,mid,rt<<1 10 #define rson mid+1,r,rt<<1|1 11 const int N = 300010; 12 const int MOD = 1e9+7; 13 #define LL long long 14 double const pi = acos(-1); 15 void fre() { 16 freopen("in.txt","r",stdin); 17 } 18 // inline int r() { 19 // int x=0,f=1;char ch=getchar(); 20 // while(ch>‘9‘||ch<‘0‘) {if(ch==‘-‘) f=-1;ch=getchar();} 21 // while(ch>=‘0‘&&ch<=‘9‘) { x=x*10+ch-‘0‘;ch=getchar();}return x*f; 22 // } 23 const int MAXM=1e7+10; 24 LL euler[10000010]; 25 int a[N]; 26 void Geteuler() 27 { 28 memset(euler, 0, sizeof(euler)); 29 euler[1] = 1; 30 for(LL i = 2; i < MAXM; i++) if(!euler[i]) 31 for(LL j = i; j < MAXM; j += i){ 32 if(!euler[j]) euler[j] = j; 33 euler[j] = euler[j] / i * (i-1); 34 } 35 } 36 37 struct tree{ 38 int l,r; 39 LL sum,lazy; 40 }t[N<<2]; 41 42 void pushup(int rt){ 43 t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum; 44 if(t[rt<<1].lazy==t[rt<<1|1].lazy) t[rt].lazy=t[rt<<1].lazy; 45 else t[rt].lazy=0; 46 } 47 48 void pushdown(int rt){ 49 if(t[rt].lazy){ 50 t[rt<<1].lazy=t[rt<<1|1].lazy=t[rt].lazy; 51 t[rt<<1].sum=(t[rt<<1].r-t[rt<<1].l+1)*t[rt<<1].lazy; 52 t[rt<<1|1].sum=(t[rt<<1|1].r-t[rt<<1|1].l+1)*t[rt<<1|1].lazy; 53 t[rt].lazy=0; 54 } 55 } 56 void build(int rt,int x,int y){ 57 t[rt].l=x; 58 t[rt].r=y; 59 if(x==y){ 60 t[rt].sum=a[x]; 61 t[rt].lazy=a[x]; 62 return; 63 } 64 int mid=(x+y)>>1; 65 build(rt<<1,x,mid); 66 build(rt<<1|1,mid+1,y); 67 pushup(rt); 68 } 69 70 void update1(int rt,int x,int y){ 71 if(t[rt].lazy&&t[rt].l==x&&t[rt].r==y){ 72 t[rt].sum=(t[rt].r-t[rt].l+1)*euler[t[rt].lazy]; 73 t[rt].lazy=euler[t[rt].lazy]; 74 return; 75 } 76 pushdown(rt); 77 int mid=(t[rt].l+t[rt].r)>>1; 78 if(y<=mid) update1(rt<<1,x,y); 79 else if(x>mid) update1(rt<<1|1,x,y); 80 else { 81 update1(rt<<1,x,mid); 82 update1(rt<<1|1,mid+1,y); 83 } 84 pushup(rt); 85 } 86 87 void update2(int rt,int x,int y,int z){ 88 if(t[rt].l==x&&t[rt].r==y){ 89 t[rt].lazy=z; 90 t[rt].sum=1LL*z*(t[rt].r-t[rt].l+1); 91 return; 92 } 93 pushdown(rt); 94 int mid=(t[rt].l+t[rt].r)>>1; 95 if(y<=mid) update2(rt<<1,x,y,z); 96 else if(x>mid) update2(rt<<1|1,x,y,z); 97 else { 98 update2(rt<<1,x,mid,z); 99 update2(rt<<1|1,mid+1,y,z); 100 } 101 pushup(rt); 102 } 103 104 LL query(int rt,int x,int y){ 105 if(t[rt].l==x&&t[rt].r==y){ 106 return t[rt].sum; 107 } 108 pushdown(rt); 109 int mid=(t[rt].l+t[rt].r)>>1; 110 if(y<=mid) return query(rt<<1,x,y); 111 else if(x>mid) return query(rt<<1|1,x,y); 112 else{ 113 return query(rt<<1,x,mid)+query(rt<<1|1,mid+1,y); 114 } 115 } 116 int main(){ 117 // fre(); 118 Geteuler(); 119 int T; 120 scanf("%d",&T); 121 while(T--){ 122 int n,m; 123 scanf("%d%d",&n,&m); 124 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 125 build(1,1,n); 126 while(m--){ 127 int op,x,y,z; 128 scanf("%d%d%d",&op,&x,&y); 129 if(op==1) update1(1,x,y); 130 else if(op==2) { 131 scanf("%d",&z); 132 update2(1,x,y,z); 133 } 134 else { 135 // cout<<"sdf"<<endl; 136 LL ans=query(1,x,y); 137 printf("%I64d\n",ans); 138 } 139 } 140 } 141 return 0; 142 }
时间: 2024-10-21 15:09:45