312 lines
7.3 KiB
C++
312 lines
7.3 KiB
C++
#include <bits/stdc++.h>
|
|
#include <ext/pb_ds/assoc_container.hpp> // Common file
|
|
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
|
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
|
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
|
|
#pragma GCC optimize("Ofast")
|
|
#pragma GCC optimize("fast-math")
|
|
#pragma GCC optimize("unroll-loops")
|
|
#pragma GCC target("avx2")
|
|
using namespace std;
|
|
using namespace __gnu_pbds;
|
|
mt19937_64 rng(chrono::steady_clock().now().time_since_epoch().count());
|
|
typedef tree<
|
|
int,
|
|
null_type,
|
|
less<int>,
|
|
rb_tree_tag,
|
|
tree_order_statistics_node_update>
|
|
ordered_set;
|
|
struct custom_hash {
|
|
static uint64_t splitmix64(uint64_t x) {
|
|
// http://xorshift.di.unimi.it/splitmix64.c
|
|
x += 0x9e3779b97f4a7c15;
|
|
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
|
|
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
|
|
return x ^ (x >> 31);
|
|
}
|
|
|
|
size_t operator()(uint64_t x) const {
|
|
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
|
|
return splitmix64(x + FIXED_RANDOM);
|
|
}
|
|
};
|
|
typedef long long ll;
|
|
typedef unsigned long long ull;
|
|
typedef long double ld;
|
|
typedef pair<ll,ll> pll;
|
|
typedef pair<int,int> pii;
|
|
int n,m,k,a[755][755];
|
|
int rmq_st[14][2*755][2*755],rmq_dr[14][2*755][2*755],nmat[2*755][2*755],loga[200005];
|
|
pair<int, int> st[2*755][2*755], dr[2*755][2*755];
|
|
int mini[200005],sol[755*755];
|
|
bool inside(int lin, int col)
|
|
{
|
|
return (lin>=1 && lin<=n && col>=1 && col<=m);
|
|
}
|
|
|
|
void la_dreapta()
|
|
{
|
|
int cnt=0, i, j, k,lin,col;
|
|
for(i=1; i<=n; i++)
|
|
{
|
|
++cnt; nmat[cnt][0]=0;
|
|
lin=i; col=1;
|
|
while(inside(lin, col))
|
|
{
|
|
nmat[cnt][++nmat[cnt][0]]=a[lin][col];
|
|
dr[lin][col]={cnt, nmat[cnt][0]};
|
|
col++; lin--;
|
|
}
|
|
}
|
|
for(i=2; i<=m; i++)
|
|
{
|
|
++cnt; nmat[cnt][0]=0;
|
|
lin=n; col=i;
|
|
while(inside(lin, col))
|
|
{
|
|
nmat[cnt][++nmat[cnt][0]]=a[lin][col];
|
|
dr[lin][col]={cnt, nmat[cnt][0]};
|
|
lin--; col++;
|
|
}
|
|
}
|
|
for(i=1; i<=cnt; i++)
|
|
{
|
|
for(j=nmat[i][0]; j>=1; j--)
|
|
{
|
|
rmq_dr[0][i][j]=nmat[i][j];
|
|
for(k=1; k<=12; k++)
|
|
{
|
|
rmq_dr[k][i][j]=rmq_dr[k-1][i][j];
|
|
int poz=j+(1<<(k-1));
|
|
if(poz<=nmat[i][0])
|
|
rmq_dr[k][i][j]=max(rmq_dr[k][i][j], rmq_dr[k-1][i][poz]);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
void la_stanga()
|
|
{
|
|
int cnt=0, i, j, k, lin, col;
|
|
for(i=1; i<=n; i++)
|
|
{
|
|
++cnt; nmat[cnt][0]=0;
|
|
lin=i; col=m;
|
|
while(inside(lin, col))
|
|
{
|
|
nmat[cnt][++nmat[cnt][0]]=a[lin][col];
|
|
st[lin][col]={cnt, nmat[cnt][0]};
|
|
col--; lin--;
|
|
}
|
|
}
|
|
for(i=m-1; i>=1; i--)
|
|
{
|
|
++cnt; nmat[cnt][0]=0;
|
|
lin=n; col=i;
|
|
while(inside(lin, col))
|
|
{
|
|
nmat[cnt][++nmat[cnt][0]]=a[lin][col];
|
|
st[lin][col]={cnt, nmat[cnt][0]};
|
|
lin--; col--;
|
|
}
|
|
}
|
|
for(i=1; i<=cnt; i++)
|
|
{
|
|
for(j=nmat[i][0]; j>=1; j--)
|
|
{
|
|
rmq_st[0][i][j]=nmat[i][j];
|
|
for(k=1; k<=12; k++)
|
|
{
|
|
rmq_st[k][i][j]=rmq_st[k-1][i][j];
|
|
int poz=j+(1<<(k-1));
|
|
if(poz<=nmat[i][0])
|
|
rmq_st[k][i][j]=max(rmq_st[k][i][j], rmq_st[k-1][i][poz]);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
int rmq_query_dr(int lin, int st, int dr)
|
|
{
|
|
ll lg=loga[dr-st+1];
|
|
return max(rmq_dr[lg][lin][st], rmq_dr[lg][lin][dr-(1<<lg)+1]);
|
|
}
|
|
|
|
int rmq_query_st(int lin, int st, int dr)
|
|
{
|
|
ll lg=loga[dr-st+1];
|
|
return max(rmq_st[lg][lin][st], rmq_st[lg][lin][dr-(1<<lg)+1]);
|
|
}
|
|
|
|
int query_st(int l1, int c1, int l2, int c2)
|
|
{
|
|
pair<int, int> p1=st[l1][c1], p2=st[l2][c2];
|
|
if(p1.first!=p2.first) return -1;
|
|
return rmq_query_st(p1.first, p1.second, p2.second);
|
|
}
|
|
|
|
int query_dr(int l1, int c1, int l2, int c2)
|
|
{
|
|
pair<int, int> p1=dr[l1][c1], p2=dr[l2][c2];
|
|
if(p1.first!=p2.first) return -1;
|
|
return rmq_query_dr(p1.first, p1.second, p2.second);
|
|
}
|
|
int main()
|
|
{
|
|
ios_base::sync_with_stdio(false);
|
|
cin.tie(0);
|
|
cout.tie(0);
|
|
mini[0]=1e9;
|
|
for(int i=1;i<=2e5;i++)
|
|
{
|
|
mini[i]=1e9;
|
|
for(int bit=0;bit<=20;bit++)
|
|
if((1<<bit)<=i)
|
|
loga[i]=bit;
|
|
}
|
|
cin>>n>>m>>k;
|
|
cin.get();
|
|
for(int i=1;i<=n;i++)
|
|
{
|
|
string s;
|
|
getline(cin,s);
|
|
int nr=0;
|
|
int j=1;
|
|
for(char c:s)
|
|
{
|
|
if(isdigit(c))
|
|
nr=nr*10+c-'0';
|
|
else
|
|
{
|
|
a[i][j]=nr;
|
|
j++;
|
|
nr=0;
|
|
}
|
|
}
|
|
a[i][j]=nr;
|
|
}
|
|
for(int i=1;i<=n*m;i++)
|
|
sol[i]=-1;
|
|
la_dreapta();
|
|
la_stanga();
|
|
int ind=0;
|
|
while(k--)
|
|
{
|
|
ind++;
|
|
int x,y;
|
|
cin>>x>>y;
|
|
vector<int> v;
|
|
int maxim=a[x][y];
|
|
v.push_back(maxim);
|
|
for(int L=1;L<=n+m;L++)
|
|
{
|
|
int i2=x-L;
|
|
int j2=y;
|
|
int i1=x;
|
|
int j1=y-L;
|
|
if(i2<=0)
|
|
{
|
|
int add=1-i2;
|
|
add=abs(add);
|
|
i2+=add;
|
|
j2-=add;
|
|
}
|
|
if(j1<=0)
|
|
{
|
|
int add=1-j1;
|
|
add=abs(add);
|
|
j1+=add;
|
|
i1-=add;
|
|
}
|
|
|
|
if(i1>=i2&&j1<=j2&&inside(i1,j1)&&inside(i2,j2))
|
|
maxim=max(maxim,query_dr(i1,j1,i2,j2));
|
|
|
|
i1=x;
|
|
j1=y+L;
|
|
if(j1>m)
|
|
{
|
|
int add=j1-m;
|
|
add=abs(add);
|
|
j1-=add;
|
|
i1-=add;
|
|
}
|
|
i2=x-L;
|
|
j2=y;
|
|
if(i2<=0)
|
|
{
|
|
int add=1-i2;
|
|
add=abs(add);
|
|
i2+=add;
|
|
j2+=add;
|
|
}
|
|
|
|
if(i1>=i2&&j1>=j2&&inside(i1,j1)&&inside(i2,j2))
|
|
maxim=max(maxim,query_st(i1,j1,i2,j2));
|
|
|
|
|
|
i1=x+L;
|
|
j1=y;
|
|
i2=x;
|
|
j2=y+L;
|
|
|
|
if(i1>n)
|
|
{
|
|
int add=i1-n;
|
|
add=abs(add);
|
|
i1-=add;
|
|
j1+=add;
|
|
}
|
|
|
|
if(j2>m)
|
|
{
|
|
int add=j2-m;
|
|
add=abs(add);
|
|
j2-=add;
|
|
i2+=add;
|
|
}
|
|
|
|
if(i1>=i2&&j1<=j2&&inside(i1,j1)&&inside(i2,j2))
|
|
maxim=max(maxim,query_dr(i1,j1,i2,j2));
|
|
|
|
i2=x;
|
|
j2=y-L;
|
|
if(j2<1)
|
|
{
|
|
int add=1-j2;
|
|
add=abs(add);
|
|
j2+=add;
|
|
i2+=add;
|
|
}
|
|
i1=x+L;
|
|
j1=y;
|
|
if(i1>n)
|
|
{
|
|
int add=i1-n;
|
|
add=abs(add);
|
|
i1-=add;
|
|
j1-=add;
|
|
}
|
|
|
|
if(i1>=i2&&j1>=j2&&inside(i1,j1)&&inside(i2,j2))
|
|
maxim=max(maxim,query_st(i1,j1,i2,j2));
|
|
v.push_back(maxim);
|
|
}
|
|
for(int i=0;i<v.size();i++)
|
|
mini[i]=min(mini[i],v[i]);
|
|
}
|
|
int poz=1;
|
|
for(int i=0;i<=n+m;i++)
|
|
{
|
|
for(int a=poz;a<=mini[i];a++)
|
|
sol[a]=i;
|
|
poz=mini[i]+1;
|
|
}
|
|
for(int i=1;i<=n*m;i++)
|
|
cout<<sol[i]<<' ';
|
|
return 0;
|
|
}
|