UOJ#218 【UNR #1】火车管理

来源:互联网 发布:android ant for mac 编辑:程序博客网 时间:2024/06/05 05:04

遥想当年,xuruifan想用线段树套可持久化treap日这题,结果最后也只得了80分……

为了不步xuruifan的后尘,我orz了题解

我们可以用一个线段树来维护当前的所有栈顶元素,支持区间覆盖和区间求和

然后我们维护一个主席树,维护每个版本的时候的栈顶元素,并维护每个栈顶元素被加入是在哪个版本,这样在区间压栈的时候我们可以区间赋值,在单点弹栈的时候我们可以先查到栈顶元素被加入的版本,然后在前一个版本即可查到弹出之后的栈顶,在主席树和线段树中修改即可

1A了,好爽啊!

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<vector>#include<map>#include<set>#include<bitset>#include<queue>#include<stack>using namespace std;#define MAXN 500010#define MAXM 20000010#define INF 1000000000#define MOD 1000000007#define eps 1e-8#define ll long longstruct data{int v;int fro;int t;data(){}data(int _v,int _fro,int _t){v=_v;fro=_fro;t=_t;}friend bool operator <(data x,data y){return x.t>y.t;}};int n,m,typ;int la;int son[MAXM][2];data v[MAXM];int tot;int sum[MAXN<<2],col[MAXN<<2];int rt[MAXN];void change(int &x,int xx,int y,int z,int l,int r,data cv){x=++tot;memcpy(son[x],son[xx],sizeof(son[x]));v[x]=v[xx];if(y==l&&z==r){v[x]=min(v[x],cv);return ;}int mid=y+z>>1;if(r<=mid){change(son[x][0],son[xx][0],y,mid,l,r,cv);}else if(l>mid){change(son[x][1],son[xx][1],mid+1,z,l,r,cv);}else{change(son[x][0],son[xx][0],y,mid,l,mid,cv);change(son[x][1],son[xx][1],mid+1,z,mid+1,r,cv);}}data ask(int x,int y,int z,int p){data re=v[x];if(y==z||!x){return re;}int mid=y+z>>1;if(p<=mid){re=min(re,ask(son[x][0],y,mid,p));}else{re=min(re,ask(son[x][1],mid+1,z,p));}return re;}inline void toch(int x,int y,int z,int cv){sum[x]=cv*(z-y+1);col[x]=cv;}inline void pd(int x,int y,int z){if(col[x]){int mid=y+z>>1;toch(x<<1,y,mid,col[x]);toch(x<<1|1,mid+1,z,col[x]);col[x]=0;}}inline void ud(int x){sum[x]=sum[x<<1]+sum[x<<1|1];}void Change(int x,int y,int z,int l,int r,int cv){if(y==l&&z==r){toch(x,y,z,cv);return ;}pd(x,y,z);int mid=y+z>>1;if(r<=mid){Change(x<<1,y,mid,l,r,cv);}else if(l>mid){Change(x<<1|1,mid+1,z,l,r,cv);}else{Change(x<<1,y,mid,l,mid,cv);Change(x<<1|1,mid+1,z,mid+1,r,cv);}ud(x);}int Ask(int x,int y,int z,int l,int r){if(y==l&&z==r){return sum[x];}pd(x,y,z);int mid=y+z>>1;if(r<=mid){return Ask(x<<1,y,mid,l,r);}else if(l>mid){return Ask(x<<1|1,mid+1,z,l,r);}else{return Ask(x<<1,y,mid,l,mid)+Ask(x<<1|1,mid+1,z,mid+1,r);}}int now=0;int main(){int o,x,y,z;scanf("%d%d%d",&n,&m,&typ);while(m--){now++;rt[now]=rt[now-1];scanf("%d",&o);if(o==1){scanf("%d%d",&x,&y);x=((ll)la*typ+x)%n+1;y=((ll)la*typ+y)%n+1;if(x>y){swap(x,y);}printf("%d\n",la=Ask(1,1,n,x,y));}if(o==2){scanf("%d",&x);x=((ll)la*typ+x)%n+1;data t=ask(rt[now],1,n,x);t=ask(rt[t.fro],1,n,x);t.t=now;change(rt[now],rt[now],1,n,x,x,t);Change(1,1,n,x,x,t.v);}if(o==3){scanf("%d%d%d",&x,&y,&z);x=((ll)la*typ+x)%n+1;y=((ll)la*typ+y)%n+1;if(x>y){swap(x,y);}change(rt[now],rt[now],1,n,x,y,data(z,now-1,now));Change(1,1,n,x,y,z);}}return 0;}/*10 10 03 1 5 31 1 63 1 7 11 1 91 1 63 1 5 21 3 61 3 93 1 7 62 1*/


0 0