uoj #228. 基础数据结构练习题

问题:

  维护一个序列,要求支持区间加法,区间开根,区间求和。


  考虑取根号很快就会取到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 }

 

posted @ 2017-01-21 10:58  №〓→龙光←  阅读(279)  评论(1编辑  收藏  举报