【题目链接】
【前置技能】
【题解】
【代码】
#include
#define INF 0x3f3f3f3f
#define LL long long
#define MAXN 300100
using namespace std;
LL n, m, Q;
template void chkmin(T &x, T y){x = min(x, y);}
template void chkmax(T &x, T y){x = max(x, y);}
template void read(T &x){
x = 0; int f = 1; char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();}
x *= f;
}
struct Segment_TreeI{
struct info{int ls, rs, sum;}a[MAXN * 100];
int root[MAXN], cnt, n;
void push_up(int pos){
a[pos].sum = a[a[pos].ls].sum + a[a[pos].rs].sum;
}
void init(int x){
n = x, cnt = 0;
}
void modify(int &pos, int l, int r, int p, int d){
if (!pos) pos = ++cnt;
if (l == r) {
a[pos].sum += d;
return;
}
int mid = (l + r) >> 1;
if (p <= mid) modify(a[pos].ls, l, mid, p, d);
else modify(a[pos].rs, mid + 1, r, p, d);
push_up(pos);
}
void modify(int T, int p, int d){
modify(root[T], 1, n, p, d);
}
LL query(int pos, int l, int r, int k){
if (l == r) return l;
int mid = (l + r) >> 1;
int tmp = (mid - l + 1) - a[a[pos].ls].sum;
if (tmp >= k) return query(a[pos].ls, l, mid, k);
else return query(a[pos].rs, mid + 1, r, k - tmp);
}
LL query(int T, int k){
return query(root[T], 1, n, k);
}
int size(int T){
return a[root[T]].sum;
}
}sgtI;
struct Segment_TreeII{
struct info{int ls, rs, sum; LL data;}a[MAXN * 100];
int root[MAXN], cnt, n, used[MAXN];
void push_up(int pos){
a[pos].sum = a[a[pos].ls].sum + a[a[pos].rs].sum;
}
void init(int x){
n = x, cnt = 0;
}
void modify(int &pos, int l, int r, int p, LL d){
if (!pos) pos = ++cnt;
if (l == r) {
a[pos].data = d;
if (d) a[pos].sum = 1;
else a[pos].sum = 0;
return;
}
int mid = (l + r) >> 1;
if (p <= mid) modify(a[pos].ls, l, mid, p, d);
else modify(a[pos].rs, mid + 1, r, p, d);
push_up(pos);
}
void modify(int T, int p, LL d){
modify(root[T], 1, n, p, d);
}
LL query(int pos, int l, int r, int k){
if (l == r) return a[pos].data;
int mid = (l + r) >> 1;
int tmp = a[a[pos].ls].sum;
if (tmp >= k) return query(a[pos].ls, l, mid, k);
else return query(a[pos].rs, mid + 1, r, k - tmp);
}
LL query(int T, int k){
return query(root[T], 1, n, k);
}
int get(int pos, int l, int r, int k){
if (l == r) return l;
int mid = (l + r) >> 1;
int tmp = a[a[pos].ls].sum;
if (tmp >= k) return get(a[pos].ls, l, mid, k);
else return get(a[pos].rs, mid + 1, r, k - tmp);
}
int get(int T, int k){
return get(root[T], 1, n, k);
}
}sgtII;
int main(){
read(n), read(m), read(Q);
sgtI.init(max(m, n));
sgtII.init(Q);
while (Q--){
int x, y; read(x), read(y);
if (y == m){
int tmp = n - sgtI.size(n + 1); LL id;
if (tmp >= x) id = 1ll * sgtI.query(n + 1, x) * m;
else id = sgtII.query(n + 1, x - tmp);
printf("%lld\n", id);
if (tmp >= x) sgtI.modify(n + 1, id / m, 1);
else sgtII.modify(n + 1, sgtII.get(n + 1, x - tmp), 0);
sgtII.modify(n + 1, ++sgtII.used[n + 1], id);
} else {
int tmp = m - sgtI.size(x) - 1;
LL id, ID;
if (tmp >= y) id = 1ll * sgtI.query(x, y) + 1ll * (x - 1) * m;
else id = sgtII.query(x, y - tmp);
ID = id;
printf("%lld\n", ID);
if (tmp >= y) sgtI.modify(x, id - 1ll * (x - 1) * m, 1);
else sgtII.modify(x, sgtII.get(x, y - tmp), 0);
tmp = n - sgtI.size(n + 1);
if (tmp >= x) id = 1ll * sgtI.query(n + 1, x) * m;
else id = sgtII.query(n + 1, x - tmp);
sgtII.modify(x, ++sgtII.used[x], id);
if (tmp >= x) sgtI.modify(n + 1, id / m, 1);
else sgtII.modify(n + 1, sgtII.get(n + 1, x - tmp), 0);
sgtII.modify(n + 1, ++sgtII.used[n + 1], ID);
}
}
return 0;
}