BZOJ1251: 序列终结者

来源:互联网 发布:并购绩效评价与优化 编辑:程序博客网 时间:2024/05/06 16:07

题目链接

1.区间加值
2.区间翻转
3.区间最大值

【代码】

#include <cstdio>#include <iostream>#include <queue>#include <vector>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#define N 50005 #define M 200005#define INF 1e9+1using namespace std;typedef long long ll;typedef pair<ll,ll> pa;int read(){    int x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}    return x*f;}int n,rt,cnt,m;int son[N][2],fa[N],num[N],sz[N],tag[N],mx[N];bool rev[N];void pushup(int k){    int l=son[k][0],r=son[k][1];    mx[k]=max(num[k],max(mx[l],mx[r]));    sz[k]=sz[l]+sz[r]+1;}void pushdown(int k){    int l=son[k][0],r=son[k][1];    if(tag[k])    {        if(l) mx[l]+=tag[k],num[l]+=tag[k],tag[l]+=tag[k];        if(r) mx[r]+=tag[k],num[r]+=tag[k],tag[r]+=tag[k];        tag[k]=0;    }    if(rev[k])    {        rev[k]=0;rev[l]^=1;rev[r]^=1;        swap(son[k][0],son[k][1]);    }}void Build(int l,int r,int f){    if(l>r) return;    if(l==r)    {        fa[l]=f;son[f][l>f]=l;        sz[l]=1;return;    }    int mid=l+r>>1;    Build(l,mid-1,mid);Build(mid+1,r,mid);    fa[mid]=f;pushup(mid);son[f][mid>f]=mid;}void Rotate(int x,int &k){    int y=fa[x],z=fa[y],l,r;    l=son[y][1]==x;r=l^1;    if(y==k) k=x;    else son[z][son[z][1]==y]=x;    fa[x]=z;fa[y]=x;fa[son[x][r]]=y;    son[y][l]=son[x][r];son[x][r]=y;    pushup(y);pushup(x);}void Splay(int x,int &k){    while(x!=k)    {        int y=fa[x],z=fa[y];        if(y!=k) {            if(son[z][0]==y^son[y][0]==x) Rotate(x,k);            Rotate(y,k);        }        Rotate(x,k);    }}int Find(int k,int x){    if(tag[k]||rev[k]) pushdown(k);    int l=son[k][0],r=son[k][1];    if(sz[l]+1==x) return k;    if(sz[l]+1>x) return Find(l,x);    return Find(r,x-sz[l]-1);}void Update(int l,int r,int w){    int x=Find(rt,l);int y=Find(rt,r+2);    Splay(x,rt);Splay(y,son[x][1]);    int z=son[y][0];num[z]+=w;mx[z]+=w;tag[z]+=w;}void Reverse(int l,int r){    int x=Find(rt,l);int y=Find(rt,r+2);    Splay(x,rt);Splay(y,son[x][1]);    int z=son[y][0];rev[z]^=1;}void Query(int l,int r){    int x=Find(rt,l);int y=Find(rt,r+2);    Splay(x,rt);Splay(y,son[x][1]);    int z=son[y][0];printf("%d\n",mx[z]);}int main(){    n=read();m=read();    mx[0]=-INF;    Build(1,n+2,0);rt=n+3>>1;    for(int i=1;i<=m;i++)    {        static int f,x,y,z;        f=read(),x=read(),y=read();        if(f==1) z=read(),Update(x,y,z);        else if(f==2) Reverse(x,y);        else Query(x,y);    }    return 0;}
0 0