标签:
题目大意
网上有许多题,就是给定一个序列,要你支持几种操作:A、B、C、D。一看另一道题,又是一个序列要支持几种操作:D、C、B、A。尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思。这道题目 就叫序列终结者吧。【问题描述】 给定一个长度为N的序列,每个序列的元素是一个整数(废话)。要支持以下三种操作: 1. 将 [L, R] 这个区间内的所有数加上 V。 2. 将 [L,R] 这个区间翻转,比如 1 2 3 4 变成 4 3 2 1。3. 求 [L,R] 这个区间中的最大值。最开始所有元素都是 0。
第一行两个整数 N,M。M 为操作个数。以下 M 行,每行最多四个整数,依次为 K, L, R, V。K 表示是第几种操作,如果不是第 1 种操作则 K 后面只有两个数。对于每个第3种操作,给出正确的回答。
【数据范围】N<=50000,M<=100000。
1 #include<iostream> 2 #include<cstdio> 3 #define inf 0x7fffffff 4 using namespace std; 5 inline int read() 6 { 7 int x=0,f=1;char ch=getchar(); 8 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 9 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 10 return x*f; 11 } 12 int n,m,sz,root; 13 int fa[50005],c[50005][2],id[50005]; 14 int tag[50005],v[50005],mx[50005],size[50005]; 15 bool rev[50005]; 16 void pushup(int k){ 17 int l=c[k][0],r=c[k][1]; 18 mx[k]=max(mx[l],mx[r]); 19 mx[k]=max(mx[k],v[k]); 20 size[k]=size[l]+size[r]+1; 21 } 22 23 void pushdown(int k){ 24 int l=c[k][0],r=c[k][1],t=tag[k]; 25 if (t){ 26 tag[k]=0; 27 if (l){tag[l]+=t;mx[l]+=t;v[l]+=t;} 28 if (r){tag[r]+=t;mx[r]+=t;v[r]+=t;} 29 } 30 if (rev[k]){ 31 rev[k]=0; 32 rev[l]^=1;rev[r]^=1; 33 swap(c[k][0],c[k][1]); 34 } 35 } 36 37 void rotate(int x,int &k){ 38 int y=fa[x],z=fa[y],l,r; 39 if (c[y][0]==x)l=0;else l=1; r=l^1; 40 if (y==k) k=x; 41 else{ 42 if (c[z][0]==y)c[z][0]=x;else c[z][1]=x; 43 } 44 fa[x]=z;fa[y]=x;fa[c[x][r]]=y; 45 c[y][l]=c[x][r];c[x][r]=y; 46 pushup(y);pushup(x); 47 } 48 49 void splay(int x,int &k){ 50 while (x!=k){ 51 int y=fa[x],z=fa[y]; 52 if (y!=k){ 53 if ((c[y][0]==x)^(c[z][0]==y)) rotate(x,k); 54 else rotate(y,k); 55 } 56 rotate(x,k); 57 } 58 } 59 60 int find(int k,int rank){ 61 if (tag[k]||rev[k]) pushdown(k); 62 int l=c[k][0],r=c[k][1]; 63 if (size[l]+1==rank) return k; 64 else if (size[l]>=rank) return find(l,rank); 65 else return find(r,rank-size[l]-1); 66 } 67 68 void updata(int l,int r,int val){ 69 int x=find(root,l),y=find(root,r+2); 70 splay(x,root);splay(y,c[x][1]); 71 int z=c[y][0]; 72 tag[z]+=val;v[z]+=val;mx[z]+=val; 73 } 74 75 void rever(int l,int r){ 76 int x=find(root,l),y=find(root,r+2); 77 splay(x,root);splay(y,c[x][1]); 78 int z=c[y][0]; 79 rev[z]^=1; 80 } 81 82 void query(int l,int r){ 83 int x=find(root,l),y=find(root,r+2); 84 splay(x,root);splay(y,c[x][1]); 85 int z=c[y][0]; 86 printf("%d\n",mx[z]); 87 } 88 89 void build(int l,int r,int f){ 90 if (l>r) return; 91 int now=id[l],last=id[f]; 92 if (l==r){ 93 fa[now]=last; size[now]=1; 94 if (l<f)c[last][0]=now; 95 else c[last][1]=now; 96 return; 97 } 98 int mid=(l+r)>>1;now=id[mid]; 99 build(l,mid-1,mid);build(mid+1,r,mid); 100 fa[now]=last;pushup(now); 101 if (mid<f) c[last][0]=now; 102 else c[last][1]=now; 103 } 104 105 int main(){ 106 mx[0]=-inf; 107 n=read();m=read(); 108 for (int i=1;i<=n+2;i++) id[i]=++sz; 109 build(1,n+2,0); root=(n+3)>>1; 110 for (int i=1;i<=m;i++){ 111 int f=read(),l,r,val; 112 switch(f){ 113 case 1:l=read();r=read();val=read(); 114 updata(l,r,val);break; 115 case 2:l=read();r=read(); 116 rever(l,r);break; 117 case 3:l=read();r=read(); 118 query(l,r);break; 119 } 120 } 121 }
修复序列
#include<bits/stdc++.h> #define inf 1000000000 #define N 1000005 using namespace std; int n,m,rt,cnt; int a[N],id[N],fa[N],tr[N][2]; int sum[N],size[N],v[N],mx[N],lx[N],rx[N]; bool tag[N],rev[N]; queue<int> q; int read() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } void updata(int x){ int l=tr[x][0],r=tr[x][1]; sum[x]=sum[l]+sum[r]+v[x]; size[x]=size[l]+size[r]+1; mx[x]=max(mx[l],mx[r]); mx[x]=max(mx[x],rx[l]+v[x]+lx[r]);//最大值 lx[x]=max(lx[l],sum[l]+v[x]+lx[r]);//左边最大值 rx[x]=max(rx[r],sum[r]+v[x]+rx[l]);//右边最大值 不会重复吗? } void pushdown(int x){ int l=tr[x][0],r=tr[x][1]; if (tag[x]){ rev[x]=tag[x]=0; if (l) tag[l]=1,v[l]=v[x],sum[l]=v[x]*size[l]; if (r) tag[r]=1,v[r]=v[x],sum[r]=v[x]*size[r]; if (v[x]>=0){ if (l) lx[l]=rx[l]=mx[l]=sum[l]; if (r) lx[r]=rx[r]=mx[r]=sum[r]; } else{ if (l)lx[l]=rx[l]=0,mx[l]=v[x]; if (r)lx[r]=rx[r]=0;mx[r]=v[x]; } if (rev[x]){ rev[x]^=1;rev[l]^=1;rev[r]^=1; swap(lx[l],rx[l]);swap(lx[r],rx[r]); swap(tr[l][0],tr[l][1]);swap(tr[r][0],tr[r][1]); } } } void rotate(int x,int &k){ int y=fa[x],z=fa[y],l,r; l=(tr[y][1]==x);r=l^1; if (y==k) k=x; else tr[z][tr[z][1]==y]=x; fa[tr[x][r]]=y;fa[y]=x;fa[x]=z; tr[y][l]=tr[x][r];tr[x][r]=y; updata(y);updata(x); } void splay(int x,int &k){ while (x!=k){ int y=fa[x],z=fa[y]; if (y!=k){ if ((tr[z][0]==y)^tr[y][0]==x) rotate(x,k); else rotate(y,k); } rotate(x,k); } } int find(int x,int rk){ pushdown(x); int l=tr[x][0],r=tr[x][1]; if (size[l]+1==rk) return x; if (size[l]>=rk) return find(l,rk); return find(r,rk-size[l]-1); } void rec(int x){ if (!x) return; int l=tr[x][0],r=tr[x][1]; rec(l);rec(r);q.push(x);//? fa[x]=tr[x][0]=tr[x][1]=0; tag[x]=rev[x]=0; } int split(int k,int tot){ int x=find(rt,k),y=find(rt,k+tot+1);//分裂出的长度 splay(x,rt);splay(y,tr[x][1]); return tr[y][0]; } void modify(int k,int tot,int val){ int x=split(k,tot),y=fa[x]; v[x]=val;tag[x]=1;sum[x]=size[x]*val; if (val>=0) lx[x]=rx[x]=mx[x]=sum[x]; else lx[x]=rx[x]=0,mx[x]=val; updata(y);updata(fa[y]); } void query(int k,int tot){ int x=split(k,tot); printf("%d\n",sum[x]); } void rever(int k,int tot){ int x=split(k,tot),y=fa[x]; if (!tag[x]){ rev[x]^=1; swap(tr[x][0],tr[x][1]); swap(lx[x],rx[x]); updata(y);updata(fa[y]); } } void build(int l,int r,int f){ if (l>r) return; int mid=(l+r)>>1,now=id[mid],last=id[f]; if (l==r){ sum[now]=a[l];size[now]=1; tag[now]=rev[now]=0; if (a[l]>=0)lx[now]=rx[now]=mx[now]=a[l]; else lx[now]=rx[now]=0,mx[now]=a[l]; } else build(l,mid-1,mid),build(mid+1,r,mid); v[now]=a[mid];fa[now]=last;updata(now); tr[last][mid>=f]=now;//懒惰的hzwer } void insert(int k,int tot){ for (int i=1;i<=tot;i++) a[i]=read(); for (int i=1;i<=tot;i++){ if (!q.empty()) id[i]=q.front(),q.pop(); else id[i]=++cnt; } build(1,tot,0);int z=id[(1+tot)>>1]; int x=find(rt,k+1),y=find(rt,k+2); splay(x,rt); splay(y,tr[x][1]); fa[z]=y;tr[y][0]=z; updata(y);updata(x); } void del(int k,int tot){ int x=split(k,tot),y=fa[x]; rec(x);tr[y][0]=0; updata(y);updata(fa[y]); } int main(){ n=read();m=read(); mx[0]=a[1]=a[n+2]=-inf; for (int i=1;i<=n;i++) a[i+1]=read(); for (int i=1;i<=n+2;i++)id[i]=i; build(1,n+2,0); rt=(n+3)>>1;cnt=n+2; int k,tot,val; char ch[10]; while (m--){ scanf("%s",ch); if (ch[0]!=‘M‘||ch[2]!=‘X‘)k=read(),tot=read(); if (ch[0]==‘I‘)insert(k,tot); if (ch[0]==‘D‘)del(k,tot); if (ch[0]==‘M‘){ if (ch[2]==‘X‘) printf("%d\n",mx[rt]); else val=read(),modify(k,tot,val); } if (ch[0]==‘R‘)rever(k,tot); if (ch[0]==‘G‘)query(k,tot); } return 0; }
标签:
原文地址:http://www.cnblogs.com/wuminyan/p/5119670.html