蒟蒻的垂死挣扎
noip2018 D2T3 大毒瘤题 emmmmm................
这题最开始的想法是大力开两棵splay,一棵维护除右边一列的所有节点,一棵维护右边一列,然后yy了很久发现可做,开心的要死,然后开始码,越码越不爽,然后去找了yl dalao (%%%),然后发现可以直接每一行开一棵splay,这样会快很多,(带着所有点一起跑真的是不要命),然后大力学一波struct写函数的操作,美滋滋。
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#define RG register
#define N 2000000
#define ls s[x][0]
#define rs s[x][1]
#define ll long long
#define ld long double
using namespace std;
inline int read(){
RG int x=0,o=1; RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if(ch=='-') o=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*o;
}
ll siz[N],le[N],fa[N],ri[N]; int s[N][2],n,m,q,tot;
struct SplayTree{
int root;
ll Add(RG ll x,RG ll y){
le[++tot]=x,ri[tot]=y,siz[tot]=y-x;
return tot;
}
void Pushup(RG int x){
siz[x]=siz[ls]+siz[rs]+ri[x]-le[x];
}
void Rotate(RG int x){
RG int y=fa[x],z=fa[y],k=s[y][1]==x,ot=s[x][k^1];
s[x][k^1]=y,s[y][k]=ot; if(z) s[z][s[z][1]==y]=x;
fa[x]=z,fa[y]=x; if(ot) fa[ot]=y; Pushup(y),Pushup(x);
}
void Splay(RG int x){
while(fa[x]){
RG int y=fa[x],z=fa[y];
if(z) (s[y][1]==x)^(s[z][1]==y)?Rotate(x):Rotate(y);
Rotate(x);
} root=x;
}
int Split(RG int x,RG ll K){
K+=le[x]; RG int y=Add(K,ri[x]); ri[x]=K;
if(!rs) fa[y]=x,rs=y;
else{ x=rs;
while(ls) x=ls;
fa[y]=x,ls=y;
} Splay(y); return y;
}
ll Delkth(RG ll K){
RG int x=root;
while(233){
if(K>siz[ls]+ri[x]-le[x]) K-=siz[ls]+ri[x]-le[x],x=rs;
else if(K<=siz[ls]) x=ls;
else{
K-=siz[ls];
if(K<ri[x]-le[x]) Split(x,K);
if(K>1) x=Split(x,K-1);
break ;
}
} Splay(x),fa[ls]=fa[rs]=0;
if(!ls) root=rs;
else{
RG int y=ls;
while(s[y][1]) y=s[y][1];
Splay(y),root=fa[s[y][1]=rs]=y;
Pushup(y);
} return le[x];
}
void Insert(RG ll K){
RG int y=Add(K,K+1);
if(!root) root=y;
else{
RG int x=root;
while(rs) x=rs;
Splay(x),fa[rs=y]=x,Pushup(x);
}
}
}Splay[N];
int main(){
n=read(),m=read(),q=read();
for(RG int i=1;i<=n;++i) Splay[i].root=Splay[i].Add(1LL*i*m-m+1,1LL*i*m);
for(RG int i=1;i<=n;++i) Splay[0].Insert(1LL*i*m);
while(q--){
RG int x=read(),y=read();RG ll ans=0;
Splay[x].Insert(Splay[0].Delkth(x));
printf("%lld\n",ans=Splay[x].Delkth(y));
Splay[0].Insert(ans);
} return 0;
}