判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence

  1 // 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence
  2 // 题意:三种操作,1增加值,2开根,3求和
  3 // 思路:这题与HDU 4027 和HDU 5634 差不多
  4 // 注意开根号的话,遇到极差等于1的,开根号以后有可能还是差1.如
  5 // 2 3 2 3。。。
  6 // 8 9 8 9。。。
  7 // 2 3 2 3。。。
  8 // 8 9 8 9。。。
  9 // 剩下就是遇到区间相等的话,就直接开根号不往下传
 10 
 11 
 12 #include <bits/stdc++.h>
 13 using namespace std;
 14 #define LL long long
 15 const int inf = 0x3f3f3f3f;
 16 const int MOD =998244353; 
 17 const int N =1e5+10; 
 18 #define clc(a,b) memset(a,b,sizeof(a))
 19 const double eps = 1e-7;
 20 void fre(){freopen("in.txt","r",stdin);}
 21 void freout() {freopen("out.txt","w",stdout);}
 22 inline int read() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
 23 int n,q;
 24 int a[N];
 25 struct node{
 26     int l,r,len;
 27     LL sum,lazy;
 28     LL mx,mn;
 29 }t[N<<2];
 30 
 31 void pushup(int rt){
 32     t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
 33     t[rt].mx=max(t[rt<<1].mx,t[rt<<1|1].mx);
 34     t[rt].mn=min(t[rt<<1|1].mn,t[rt<<1].mn);
 35 }
 36 void pushdown(int rt){
 37     if(t[rt].lazy){
 38         t[rt<<1].lazy+=t[rt].lazy;
 39         t[rt<<1].mx+=t[rt].lazy;
 40         t[rt<<1].mn+=t[rt].lazy;
 41         t[rt<<1].sum+=t[rt<<1].len*t[rt].lazy;
 42         t[rt<<1|1].lazy+=t[rt].lazy;
 43         t[rt<<1|1].mx+=t[rt].lazy;
 44         t[rt<<1|1].mn+=t[rt].lazy;
 45         t[rt<<1|1].sum+=t[rt<<1|1].len*t[rt].lazy;
 46         t[rt].lazy=0;
 47     }
 48 }
 49 void build(int rt,int l,int r){
 50     t[rt].l=l;
 51     t[rt].r=r;
 52     t[rt].lazy=0;
 53     t[rt].mx=0;
 54     t[rt].mn=inf;
 55     t[rt].len=r-l+1;
 56     if(l==r){
 57        t[rt].sum=a[l],t[rt].mx=t[rt].mn=a[l];
 58        return;    
 59     }
 60     int mid=(l+r)>>1;
 61     build(rt<<1,l,mid);
 62     build(rt<<1|1,mid+1,r);
 63     pushup(rt);
 64 }
 65 
 66 void update1(int rt,int l,int r,int z){
 67     if(t[rt].l>=l&&t[rt].r<=r){
 68         t[rt].sum+=(LL)t[rt].len*z;
 69         t[rt].lazy+=z;
 70         t[rt].mn+=z;
 71         t[rt].mx+=z;
 72         return;
 73     }
 74     pushdown(rt);
 75     int mid=(t[rt].l+t[rt].r)>>1;
 76     if(r<=mid) update1(rt<<1,l,r,z);
 77     else if(l>mid) update1(rt<<1|1,l,r,z);
 78     else {
 79         update1(rt<<1,l,mid,z);
 80         update1(rt<<1|1,mid+1,r,z);
 81     }
 82     pushup(rt);
 83 }
 84 
 85 void update2(int rt,int l,int r){
 86     if(t[rt].l>=l&&t[rt].r<=r){
 87         if(t[rt].mx==t[rt].mn){
 88            LL tem=(LL)sqrt(t[rt].mx);
 89            t[rt].sum=(LL)tem*t[rt].len;
 90            t[rt].lazy-=(t[rt].mx-tem);
 91            t[rt].mx=t[rt].mn=tem;
 92            return;
 93         }
 94         else if(t[rt].mx==t[rt].mn+1){
 95             LL tem1=(LL)sqrt(t[rt].mx);
 96             LL tem2=(LL)sqrt(t[rt].mn);
 97             if(tem1==tem2+1){
 98                 t[rt].sum-=(LL)(t[rt].mx-tem1)*t[rt].len;
 99                 t[rt].lazy-=(t[rt].mx-tem1);
100                 t[rt].mx=tem1;
101                 t[rt].mn=tem2;
102                 return;
103             }
104         }
105     }
106     pushdown(rt);
107     int mid=(t[rt].l+t[rt].r)>>1;
108     if(r<=mid) update2(rt<<1,l,r);
109     else if(l>mid) update2(rt<<1|1,l,r);
110     else {
111         update2(rt<<1,l,mid);
112         update2(rt<<1|1,mid+1,r);
113     }
114     pushup(rt);
115 }
116 
117 LL query(int rt,int l,int r){
118     if(t[rt].l>=l&&t[rt].r<=r){
119         return t[rt].sum;
120     }
121     pushdown(rt);
122     int mid=(t[rt].l+t[rt].r)>>1;
123     if(r<=mid) return query(rt<<1,l,r);
124     else if(l>mid) return query(rt<<1|1,l,r);
125     else {
126         return query(rt<<1,l,mid)+query(rt<<1|1,mid+1,r);
127     }
128 }
129 int main(){
130     int T;
131     scanf("%d",&T);
132     while(T--){
133        scanf("%d%d",&n,&q);
134        for(int i=1;i<=n;i++) {
135         scanf("%d",&a[i]);
136        }
137        build(1,1,n);
138        while(q--){
139            int op,x,y,z;
140            scanf("%d%d%d",&op,&x,&y);
141            if(op==1){
142                scanf("%d",&z);
143                update1(1,x,y,z);
144            }
145            else if(op==2){
146                update2(1,x,y);
147            } 
148            else {
149                LL ans=query(1,x,y);
150                printf("%I64d\n",ans);
151            }
152        }
153     }
154     return 0;
155 }

 

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