问题:
维护一个序列,要求支持区间加法,区间开根,区间求和。
考虑取根号很快就会取到0,维护区间最大最小值,如果一样就是区间覆盖问题,然后发现TLE了,原因是可能存在一种情况8 9 8 9 8 9。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 100100 10 #define llg register long long 11 #define llG register long long 12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 13 long long n,m,L,R,Q,ty; 14 15 inline int getint() 16 { 17 register int w=0,q=0; char c=getchar(); 18 while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 19 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w; 20 } 21 22 struct node 23 { 24 long long min,max,v,add; 25 }a[maxn*5]; 26 27 inline void update(llg o,llg l,llg r) 28 { 29 llg lc=(o<<1),rc=(o<<1)|1;//,mid=(l+r)>>1; 30 a[o].min=min(a[lc].min,a[rc].min)+a[o].add; 31 a[o].max=max(a[lc].max,a[rc].max)+a[o].add; 32 a[o].v=a[lc].v+a[rc].v+a[o].add*(r-l+1); 33 } 34 35 inline void sqr(llg o,llg l,llg r,llg L,llg R,llG add) 36 { 37 llg lc=(o<<1),rc=(o<<1)|1,mid=(l+r)>>1; 38 llG VAL=add+a[o].add; 39 if (l>=L && r<=R) 40 { 41 if ((a[o].min==a[o].max) || ((a[o].min+1==a[o].max) && (floor(sqrt(a[o].min+add))+1==floor(sqrt(a[o].max+add))))) 42 { 43 llG ad=sqrt(a[o].min+add); 44 ad-=a[o].min+add; 45 a[o].add+=ad; 46 a[o].min+=ad; a[o].max+=ad; 47 a[o].v+=ad*(r-l+1); 48 return ; 49 } 50 sqr(lc,l,mid,L,R,VAL); sqr(rc,mid+1,r,L,R,VAL); 51 update(o,l,r); 52 return ; 53 } 54 if (L<=mid) sqr(lc,l,mid,L,R,VAL); 55 if (R>mid) sqr(rc,mid+1,r,L,R,VAL); 56 update(o,l,r); 57 } 58 59 inline long long sum(llg o,llg l,llg r,llg L,llg R,llG add) 60 { 61 if (L<=l && r<=R) return a[o].v+add*(r-l+1); 62 llG ans=0; 63 llg lc=(o<<1),rc=(o<<1)|1,mid=(l+r)>>1; 64 if (L<=mid) ans+=sum(lc,l,mid,L,R,add+a[o].add); 65 if (R>mid) ans+=sum(rc,mid+1,r,L,R,add+a[o].add); 66 return ans; 67 } 68 69 inline void build(llg o,llg l,llg r) 70 { 71 if (l==r) 72 { 73 a[o].min=a[o].max=a[o].v=getint(); 74 return ; 75 } 76 build(o<<1,l,(l+r)>>1); build((o<<1)|1,((l+r)>>1)+1,r); 77 update(o,l,r); 78 } 79 80 inline void add(llg o,llg l,llg r,llg L,llg R,llG v) 81 { 82 if (L<=l && r<=R) 83 { 84 a[o].add+=v,a[o].v+=v*(r-l+1); 85 a[o].min+=v,a[o].max+=v; 86 return ; 87 } 88 llg lc=(o<<1),rc=(o<<1)|1,mid=(l+r)>>1; 89 if (L<=mid) add(lc,l,mid,L,R,v); 90 if (R>mid) add(rc,mid+1,r,L,R,v); 91 update(o,l,r); 92 } 93 94 int main() 95 { 96 yyj("a"); 97 cin>>n>>Q; 98 build(1,1,n); 99 while (Q--) 100 { 101 ty=getint(); L=getint(),R=getint(); 102 if (ty==1) add(1,1,n,L,R,getint()); 103 else if (ty==2) sqr(1,1,n,L,R,0); 104 else printf("%lld\n",sum(1,1,n,L,R,0)); 105 } 106 return 0; 107 }