uestc 1425 Another LCIS 线段树 区间合并
结点记录的信息:
lics:区间lics的大小
lv、rv:区间左右端点的值
lpart:以左端点为起点的ics的大小
rpart:以右端点为终点的ics的大小
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<sstream> #include<cmath> #include<climits> #include<string> #include<map> #include<queue> #include<vector> #include<stack> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pii; #define pb(a) push_back(a) #define INF 0x1f1f1f1f #define lson idx<<1,l,mid #define rson idx<<1|1,mid+1,r #define PI 3.1415926535898 template<class T> T min(const T& a,const T& b,const T& c) { return min(min(a,b),min(a,c)); } template<class T> T max(const T& a,const T& b,const T& c) { return max(max(a,b),max(a,c)); } #define clr0(a) memset(a,0,sizeof(a)) #define clr1(a) memset(a,-1,sizeof(a)) void debug() { #ifdef ONLINE_JUDGE #else freopen("d:\\in.txt","r",stdin); freopen("d:\\out1.txt","w",stdout); #endif } char getch() { char ch; while((ch=getchar())!=EOF) { if(ch!=' '&&ch!='\n')return ch; } return EOF; } struct node { int lics,lpart,rpart,lv,rv,len; node(){} node(int lics,int lpart,int rpart,int lv,int rv,int len):lics(lics),lpart(lpart),rpart(rpart),lv(lv),rv(rv),len(len){} }; const int maxn=100010; node tree[maxn<<2]; int add[maxn<<2]; int Merge(node &idx,node &a,node &b) { if(a.rv<b.lv) { idx.lics=max(a.lics,b.lics,a.rpart+b.lpart); idx.lpart=a.lpart==a.len?a.lpart+b.lpart:a.lpart; idx.rpart=b.rpart==b.len?b.rpart+a.rpart:b.rpart; }else { idx.lics=max(a.lics,b.lics); idx.lpart=a.lpart; idx.rpart=b.rpart; } idx.lv=a.lv;idx.rv=b.rv; idx.len=a.len+b.len; } int PushDown(int idx) { if(add[idx]!=0) { add[idx<<1]+=add[idx]; add[idx<<1|1]+=add[idx]; tree[idx<<1].lv+=add[idx]; tree[idx<<1].rv+=add[idx]; tree[idx<<1|1].lv+=add[idx]; tree[idx<<1|1].rv+=add[idx]; add[idx]=0; } return 0; } int Build(int idx,int l,int r) { if(l==r) { int v; scanf("%d",&v); tree[idx]=node(1,1,1,v,v,1); add[idx]=0; return 0; } int mid=(r+l)>>1; Build(lson);Build(rson); Merge(tree[idx],tree[idx<<1],tree[idx<<1|1]); add[idx]=0; return 0; } int Update(int idx,int l,int r,int tl,int tr,int v) { if(tl<=l&&tr>=r) { add[idx]+=v; tree[idx].lv+=v;tree[idx].rv+=v; return 0; } PushDown(idx); int mid=(r+l)>>1; if(tl<=mid)Update(lson,tl,tr,v); if(tr>mid)Update(rson,tl,tr,v); Merge(tree[idx],tree[idx<<1],tree[idx<<1|1]); return 0; } node Quary(int idx,int l,int r,int tl,int tr) { if(tl<=l&&tr>=r) { return tree[idx]; } PushDown(idx); int mid=(r+l)>>1; node q; if(tl<=mid&&tr>mid) { node a,b; a=Quary(lson,tl,tr); b=Quary(rson,tl,tr); Merge(q,a,b); }else if(tl<=mid) { q= Quary(lson,tl,tr); }else q= Quary(rson,tl,tr); Merge(tree[idx],tree[idx<<1],tree[idx<<1|1]); return q; } int main() { int t; scanf("%d",&t); for(int ca=1;ca<=t;ca++) { int n,q; scanf("%d%d",&n,&q); Build(1,1,n); printf("Case #%d:\n",ca); for(int i=1;i<=q;i++) { char op[10]; scanf("%s",op); if(op[0]=='a') { int l,r,v; scanf("%d%d%d",&l,&r,&v); Update(1,1,n,l,r,v); }else { int l,r; scanf("%d%d",&l,&r); node x=Quary(1,1,n,l,r); printf("%d\n",x.lics); } } } return 0; }