传送门
分析
这题是真的顶啊。。。
我们去建
n
+
1
n + 1
n+1棵权值线段树,前
n
n
n棵线段树分别表示范围内有多少,用来找到每一行第
k
k
k个数的位置,第
n
+
1
n + 1
n+1棵线段树用查找最后一列第
k
k
k个数的位置,用
v
e
c
t
o
r
vector
vector记录插入的数
因为这道题数据很大,所以要用动态开点的方式建线段树
代码
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
#define _CRT_SECURE_NO_WARNINGS
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
#define N 300005
#define M 12000005
const ll mod = 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a) {
char c = getchar(); T x = 0, f = 1; while (!isdigit(c)) {if (c == '-')f = -1; c = getchar();}
while (isdigit(c)) {x = (x << 1) + (x << 3) + c - '0'; c = getchar();} a = f * x;
}
int gcd(int a, int b) {return (b > 0) ? gcd(b, a % b) : a;}
int root[N],ls[M],rs[M],sz[M];
vector<ll> v[N];
int n,m,q,li,idx;
int query(int rt,int x,int l,int r){
if(l == r) return l;
int mid = (l + r) >> 1;
int t = mid - l + 1 - sz[ls[rt]];
if(x <= t) return query(ls[rt],x,l,mid);
return query(rs[rt],x - t,mid + 1,r);
}
void modify(int &rt,int x,int l,int r){
if(!rt) rt = ++idx;
sz[rt]++;
if(l == r) return;
int mid = (l + r) >> 1;
if(x <= mid) modify(ls[rt],x,l,mid);
else modify(rs[rt],x,mid + 1,r);
}
ll run1(int x,ll y){
int p = query(root[n + 1],x,1,li);
modify(root[n + 1],p,1,li);
ll ans;
if(p <= n) ans = 1ll * p * m;
else ans = v[n + 1][p - n - 1];
if(y) v[n + 1].pb(y);
else v[n + 1].pb(ans);
return ans;
}
ll run2(int x,int y){
int p = query(root[x],y,1,li);
modify(root[x],p,1,li);
ll ans;
if(p < m) ans = 1ll * (x - 1) * m + p;
else ans = v[x][p - m];
v[x].pb(run1(x,ans));
return ans;
}
int main() {
read(n),read(m),read(q);
li = max(m,n) + q;
while(q--){
int x,y;
read(x),read(y);
ll ans;
if(y == m) ans = run1(x,0);
else ans = run2(x,y);
dl(ans);
}
return 0;
}