• 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
    ",ans);
    138             }
    139         }
    140     }
    141     return 0;
    142 }
  • 相关阅读:
    类与类之间的几种关系
    spring之BeanFactory
    java打开本地应用程序
    java笔记六:线程间的协调
    继承与组合的优缺点
    适配器模式之对象适配器
    java笔记三:List接口
    java笔记二:final关键字用法总结
    设计模式之命令模式
    利用栈实现迷宫的求解
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5764608.html
Copyright © 2020-2023  润新知