题意简述
有一个 n × m n\times m n×m的矩阵 a a a,每个数是 [ 1 , n × m ] [1,n\times m] [1,n×m]之间的整数,并且互不相同。然后有 Q Q Q次询问,每次询问给定 x , y x,y x,y,问你有多少个数满足:它在行中是第 x x x大,在列中是第 y y y大。
n , m < = 1000 , Q < = 5 e 5 n,m<=1000,Q<=5e5 n,m<=1000,Q<=5e5。
思路框架
设
x
[
i
]
[
j
]
x[i][j]
x[i][j]表示
a
[
i
]
[
j
]
a[i][j]
a[i][j]在第
i
i
i行里第几大,
y
[
i
]
[
j
]
y[i][j]
y[i][j]表示
a
[
i
]
[
j
]
a[i][j]
a[i][j]在第
j
j
j列第几大。
设
a
n
s
[
i
]
[
j
]
ans[i][j]
ans[i][j]表示在行里排第
i
i
i大,列里排第
j
j
j大的数有多少。对于所有
i
,
j
i,j
i,j,
a
n
s
[
x
[
i
]
[
j
]
]
[
y
[
i
]
[
j
]
ans[x[i][j]][y[i][j]
ans[x[i][j]][y[i][j]++。
每次询问输出 a n s [ x ] [ y ] ans[x][y] ans[x][y]即珂。 O ( n m l o g ( n + m ) + Q ) O(nmlog(n+m)+Q) O(nmlog(n+m)+Q)
x [ i ] [ j ] x[i][j] x[i][j]和 y [ i ] [ j ] y[i][j] y[i][j],您珂以用一个 l o w e r _ b o u n d lower\_bound lower_bound解决,或者像我一样 s b sb sb的写一个树状数组。
代码
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define N 1333
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define MEM(x,a) memset(x,a,sizeof(x))
#define FK(x) MEM(x,0)
#define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))
#define p_b push_back
#define sz(a) ((int)a.size())
#define iter(a,p) (a.begin()+p)
void R1(int &x)
{
x=0;char c=getchar();int f=1;
while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=(f==1)?x:-x;
}
void Rd(int cnt,...)
{
va_list args;
va_start(args,cnt);
F(i,1,cnt)
{
int* x=va_arg(args,int*);R1(*x);
}
va_end(args);
}
class BIT
{
public:
int tree[N*N];
int len;
void BuildTree(int _len)
{
len=_len;
FK(tree);
}
void Add(int pos,int val=1)
{
for(int i=pos;i<=len;i+=(i&(-i)))
{
tree[i]+=val;
}
}
int Query(int pos)
{
int ans=0;
for(int i=pos;i>0;i-=(i&(-i)))
{
ans+=tree[i];
}
return ans;
}
}T;
int n,m,q;
int a[N][N];
void Input()
{
Rd(3,&n,&m,&q);
F(i,1,n) F(j,1,m) R1(a[i][j]);
}
int line[N][N],col[N][N];
int ans[N][N];
void Soviet()
{
T.BuildTree(n*m);
F(i,1,n)
{
F(j,1,m) T.Add(a[i][j],1);
F(j,1,m) line[i][j]=m-T.Query(a[i][j])+1;
F(j,1,m) T.Add(a[i][j],-1);
}
F(j,1,m)
{
F(i,1,n) T.Add(a[i][j],1);
F(i,1,n) col[i][j]=n-T.Query(a[i][j])+1;
F(i,1,n) T.Add(a[i][j],-1);
}
F(i,1,n) F(j,1,m) ans[line[i][j]][col[i][j]]++;
F(i,1,q)
{
int x,y;Rd(2,&x,&y);
printf("%d\n",ans[x][y]);
}
}
#define Flan void
Flan IsMyWife()
{
Input();
Soviet();
}
}
int main()
{
Flandre_Scarlet::IsMyWife();
getchar();getchar();
return 0;
}