洛谷 P3960 列队

https://www.luogu.org/problemnew/show/P3960

常数超大的treap

  1 #pragma GCC optimize("Ofast")
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<queue>
  6 #include<vector>
  7 using namespace std;
  8 #define fi first
  9 #define se second
 10 #define mp make_pair
 11 #define pb push_back
 12 typedef long long ll;
 13 typedef unsigned long long ull;
 14 typedef pair<int,int> pi;
 15 #define N 6001000
 16 queue<int> q;
 17 int ch[N][2],r[N],mem;
 18 ll lx[N],rx[N],sz[N];
 19 int rand1()
 20 {
 21     static int x=471;
 22     return x=(48271LL*x+1)%2147483647;
 23 }
 24 int getnode()
 25 {
 26     int t=q.front();q.pop();r[t]=rand1();
 27     lx[t]=rx[t]=sz[t]=ch[t][0]=ch[t][1]=0;
 28     return t;
 29 }
 30 void delnode(int x)    {q.push(x);}
 31 void upd(int x)    {sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+rx[x]-lx[x]+1;}
 32 int merge(int a,int b)
 33 {
 34     if(!a||!b)    return a+b;
 35     if(r[a]<r[b])
 36     {
 37         ch[a][1]=merge(ch[a][1],b);upd(a);
 38         return a;
 39     }
 40     else
 41     {
 42         ch[b][0]=merge(a,ch[b][0]);upd(b);
 43         return b;
 44     }
 45 }
 46 pi split(int a,ll n)
 47 {
 48     if(!a)    return mp(0,0);
 49     ll ls=sz[ch[a][0]];pi t;
 50     if(n<=ls)
 51     {
 52         t=split(ch[a][0],n);ch[a][0]=t.se;
 53         upd(a);t.se=a;
 54     }
 55     else
 56     {
 57         t=split(ch[a][1],n-ls-(rx[a]-lx[a]+1));ch[a][1]=t.fi;
 58         upd(a);t.fi=a;
 59     }
 60     return t;
 61 }
 62 int split_node(int a,ll n)
 63 {
 64     ll ls=sz[ch[a][0]];
 65     if(n<=ls)    {ch[a][0]=split_node(ch[a][0],n);return a;}
 66     else if(n<=ls+rx[a]-lx[a]+1)
 67     {
 68         n-=ls;
 69         int now=ch[a][0],rc=ch[a][1],t;ll l=lx[a],r=rx[a];
 70         if(n!=1)
 71         {
 72             t=getnode();lx[t]=l;rx[t]=l+n-2;upd(t);
 73             now=merge(now,t);
 74         }
 75         t=getnode();lx[t]=rx[t]=l+n-1;upd(t);
 76         now=merge(now,t);
 77         if(n!=r-l+1)
 78         {
 79             t=getnode();lx[t]=l+n;rx[t]=r;upd(t);
 80             now=merge(now,t);
 81         }
 82         now=merge(now,rc);delnode(a);
 83         return now;
 84     }
 85     else {ch[a][1]=split_node(ch[a][1],n-(ls+rx[a]-lx[a]+1));return a;}
 86 }
 87 int rt[300100];
 88 ll n,m;int qq;
 89 int main()
 90 {
 91     int i,t;ll x,y,ans;pi p1,p2,p3,p4;
 92     for(i=1;i<N;++i)    q.push(i);
 93     scanf("%lld%lld%d",&n,&m,&qq);
 94     for(i=1;i<=n;i++)
 95     {
 96         t=getnode();lx[t]=ll(i-1)*m+1;rx[t]=ll(i)*m-1;upd(t);
 97         rt[i]=t;
 98     }
 99     for(i=1;i<=n;i++)
100     {
101         t=getnode();lx[t]=rx[t]=i*m;upd(t);
102         rt[0]=merge(rt[0],t);
103     }
104     while(qq--)
105     {
106         scanf("%lld%lld",&x,&y);
107         if(y==m)
108         {
109             rt[0]=split_node(rt[0],x);
110             p1=split(rt[0],x-1);p2=split(p1.se,1);
111             ans=lx[p2.fi];
112             rt[0]=merge(p1.fi,merge(p2.se,p2.fi));
113         }
114         else
115         {
116             rt[x]=split_node(rt[x],y);
117             p1=split(rt[x],y-1);p2=split(p1.se,1);
118             ans=lx[p2.fi];
119             rt[x]=merge(p1.fi,p2.se);
120             rt[0]=split_node(rt[0],x);
121             p3=split(rt[0],x-1);p4=split(p3.se,1);
122             rt[x]=merge(rt[x],p4.fi);
123             rt[0]=merge(p3.fi,merge(p4.se,p2.fi));
124         }
125         printf("%lld\n",ans);
126     }
127     return 0;
128 }

 

posted @ 2018-07-09 09:17  hehe_54321  阅读(137)  评论(0编辑  收藏  举报
AmazingCounters.com