1. 程式人生 > >洛谷 P3960 列隊

洛谷 P3960 列隊

www print \n del blank std type tno fin

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 }

洛谷 P3960 列隊