HDU5634 Rikka with Phi 线段树

  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 }

 

posted @ 2016-08-12 13:35  yyblues  阅读(373)  评论(0编辑  收藏  举报