Gorgeous Sequence solution to a problem (small fresh tree line)

This question is seniors called "science fiction title"

In fact, the practice is not science fiction, but "Why can do that?" The explanation is very sci-fi

In other words, complexity analysis gray often strange that guitar like a big brother to eat on the spot books

Volume segment tree maintenance: interval and sum, the maximum range max1, the interval the second largest value max2, the maximum number of cnt appear.

Assuming now that the interval [l, r] to take x min, if the following three conditions:

1.max1 <= x, without modification, return;

2.max2 <x <max1, modifications will affect all maximum, sum + = cnt * (max1-x), update max1 marking;

3.max2> = x, violence recursive about modifying son.

Book before eating complexity of O (nlog 2 n-)

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #define ls(k) k<<1
  4 #define rs(k) k<<1|1
  5 
  6 const int L=1<<20|1;
  7 char buffer[L],*S,*TT;
  8 #define getchar() ((S==TT&&(TT=(S=buffer)+fread(buffer,1,L,stdin),S==TT))?EOF:*S++)
  9 
 10 const int N=1000005;
 11 typedef long long ll;
 12 int max(int a,int b){return a>b?a:b;}
 13 int min(int a,int b){return a<b?a:b;}
 14 int T,n,m,a[N];
 15 struct segment_tree
 16 {
 17     int max1[N<<2],max2[N<<2],cnt[N<<2];
 18     ll sum[N<<2];
 19     void up(int k)
 20     {
 21         sum[k]=sum[ls(k)]+sum [rs (k)];
22          max1 [k] = max (max1 [ls (k)], max1 [rs (k)]);
23          max2 [k] = max (max2 [ls (k)], max2 [rs (k)]);
24          CNT [k] = 0 ;
25          if (max1 [ls (k)]! = Max1 [rs (k)]) max2 [k] = max (max2 [k], min (max1 [ls (k)], max1 [rs (k)]) );
26          CNT [k] + = (max1 [k] == max1 [ls (k)]? CNT [ls (k)]: 0 );
27          CNT [k] + = (max1 [k] == max1 [rs (k)]? CNT [rs (k)]: 0 );
28      }
 29      void ( int k, int val)
 30      {
 31          if(val>=max1[k])return ;
 32         sum[k]+=(ll)(val-max1[k])*cnt[k];
 33         max1[k]=val;
 34     }
 35     void down(int k)
 36     {
 37         tag(ls(k),max1[k]);
 38         tag(rs(k),max1[k]);
 39     }
 40     void build(int k,int l,int r)
 41     {
 42         if(l==r)
 43         {
 44             sum[k]=max1[k]=a[l];
 45             cnt[k]=1;max2[k]=-1;
 46             return ;
 47         }
 48         int mid=l+r>>1;
 49         build(ls(k),l,mid);
 50         build(rs(k),mid+1,r);
 51         up(k);
 52     }
 53     void change(int k,int l,int r,int L,int R,int val)
 54     {
 55         if(val>=max1[k])return ;
 56         if(L<=l&&R>=r&&val>max2[k])
 57         {
 58             tag(k,val);
 59             return ;
 60         }
 61         int mid=l+r>>1;down(k);
 62         if(L<=mid)change(ls(k),l,mid,L,R,val);
 63         if(R>mid)change(rs(k),mid+1,r,L,R,val);
 64         up(k);
 65     }
 66     ll qsum(int k,int l,int r,int L,int R)
 67     {
 68         if(L<=l&&R>=r)return sum[k];
 69         int mid=l+r>>1;
 70         down(k);ll res=0;
 71         if(L<=mid)res+=qsum(ls(k),l,mid,L,R);
 72         if(R>mid)res+=qsum(rs(k),mid+1,r,L,R);
 73         return res;
 74     }
 75     int qmax(int k,int l,int r,int L,int R)
 76     {
 77         if(L<=l&&R>=r)return max1[k];
 78         down(k);
 79         int mid=l+r>>1,ans=-1;
 80         if(L<=mid)ans=max(ans,qmax(ls(k),l,mid,L,R));
 81         if(R>mid)ans=max(ans,qmax(rs(k),mid+1,r,L,R));
 82         return ans;
 83     }
 84 }seg;
 85 inline int read()
 86 {
 87     int x=0,f=1;char ch=getchar();
 88     while(ch<'0'||ch>'9')
 89     {if(ch=='-')f=-1;ch=getchar();}
 90     while(ch>='0'&&ch<='9')
 91     {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
 92     return x*f;
 93 }
 94 void work()
 95 {
 96     n=read();m=read();
 97     for(int i=1;i<=n;i++)a[i]=read();
 98     seg.build(1,1,n);
 99     while(m--)
100     {
101         int op=read(),l=read(),r=read();
102         if(op==0)
103         {
104             int val=read();
105             seg.change(1,1,n,l,r,val);
106         }
107         else if(op==1)printf("%d\n",seg.qmax(1,1,n,l,r));
108         else if(op==2)printf("%lld\n",seg.qsum(1,1,n,l,r));
109     }
110 }
111 int main()
112 {
113     T=read();
114     while(T--)work();
115     return 0;
116 }
View Code

 

Guess you like

Origin www.cnblogs.com/Rorschach-XR/p/11008147.html