This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#pragma GCC optimize ("O3")
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int MAXN = 1e5;
const int INF = 5e7;
int N;
pii A[MAXN+10];
vector<int> X[MAXN+10], Y[MAXN+10];
struct Line
{
int l, r, p;
Line(int l, int r, int p) : l(l), r(r), p(p) {}
bool operator < (const Line &q) const { return r<q.r; }
};
int Q;
vector<Line> LX[MAXN+10], LY[MAXN+10];
vector<int> adjX[MAXN+10], adjY[MAXN+10];
pii get(int y, int x)
{
int nx=lower_bound(LX[y].begin(), LX[y].end(), Line(0, x, 0))->p;
int ny=lower_bound(LY[x].begin(), LY[x].end(), Line(0, y, 0))->p;
return {nx, ny};
}
pii P[MAXN+10];
struct Tree
{
int M;
//vector<vector<int>> adj, cdist;
//vector<int> sz, del, cpar, cdep;
int sz[MAXN+10], del[MAXN+10], cpar[MAXN+10], cdist[MAXN+10][21], cdep[MAXN+10];
vector<int> adj[MAXN+10];
Tree()
{
M=0;
//sz=del=cpar=cdep=vector<int>(MAXN+10);
//cdist.resize(MAXN+10);
//for(auto &it : cdist) it.resize(30);
//adj.resize(MAXN+10);
}
void getsz(int now, int bef)
{
sz[now]=1;
for(int nxt : adj[now])
{
if(nxt==bef) continue;
if(del[nxt]) continue;
getsz(nxt, now);
sz[now]+=sz[nxt];
}
}
int getcen(int now, int bef, int S)
{
for(int nxt : adj[now])
{
if(nxt==bef) continue;
if(del[nxt]) continue;
if(sz[nxt]>S/2) return getcen(nxt, now, S);
}
return now;
}
void dfs(int now, int bef, int t, int dist)
{
cdist[now][t]=dist;
for(int nxt : adj[now])
{
if(nxt==bef) continue;
if(del[nxt]) continue;
dfs(nxt, now, t, dist+1);
}
}
void decomp(int now, int bef, int cendep)
{
getsz(now, now);
now=getcen(now, now, sz[now]);
cpar[now]=bef;
cdep[now]=cendep;
dfs(now, now, cendep, 0);
del[now]=true;
for(auto nxt : adj[now])
{
if(del[nxt]) continue;
decomp(nxt, now, cendep+1);
}
}
void init()
{
decomp(1, 0, 1);
}
vector<int> getpar(int now)
{
vector<int> ans;
while(now)
{
ans.push_back(now);
now=cpar[now];
}
return ans;
}
}TX, TY;
unordered_map<ll, int> M;
int main()
{
scanf("%d", &N);
for(int i=1; i<=N; i++)
{
int y, x;
//y=readInt(); x=readInt();
scanf("%d%d", &y, &x);
A[i]={y, x};
X[y].push_back(x);
Y[x].push_back(y);
}
for(int i=1; i<=MAXN; i++)
{
if(X[i].empty()) continue;
sort(X[i].begin(), X[i].end());
int bef=X[i][0];
for(int j=0; j+1<X[i].size(); j++)
{
if(X[i][j]+1<X[i][j+1])
{
LX[i].push_back({bef, X[i][j], ++TX.M});
//printf("LX %d %d %d %d\n", i, LX[i].back().l, LX[i].back().r, LX[i].back().p);
bef=X[i][j+1];
}
}
LX[i].push_back({bef, X[i].back(), ++TX.M});
//printf("LX %d %d %d %d\n", i, LX[i].back().l, LX[i].back().r, LX[i].back().p);
}
for(int i=2; i<=MAXN; i++)
{
if(LX[i].empty() || LX[i-1].empty()) continue;
int p=0;
for(auto it : LX[i])
{
for(; p<LX[i-1].size() && LX[i-1][p].r<it.l; p++);
for(; p<LX[i-1].size() && LX[i-1][p].l<=it.r; p++)
{
int u=LX[i-1][p].p, v=it.p;
TX.adj[u].push_back(v);
TX.adj[v].push_back(u);
//printf("adjX %d %d\n", u, v);
}
if(p) p--;
}
}
for(int i=1; i<=MAXN; i++)
{
if(Y[i].empty()) continue;
sort(Y[i].begin(), Y[i].end());
int bef=Y[i][0];
for(int j=0; j+1<Y[i].size(); j++)
{
if(Y[i][j]+1!=Y[i][j+1])
{
LY[i].push_back({bef, Y[i][j], ++TY.M});
//printf("LY %d %d %d %d\n", i, LY[i].back().l, LY[i].back().r, LY[i].back().p);
bef=Y[i][j+1];
}
}
LY[i].push_back({bef, Y[i].back(), ++TY.M});
//printf("LY %d %d %d %d\n", i, LY[i].back().l, LY[i].back().r, LY[i].back().p);
}
for(int i=2; i<=MAXN; i++)
{
if(LY[i].empty() || LY[i-1].empty()) continue;
int p=0;
for(auto it : LY[i])
{
for(; p<LY[i-1].size() && LY[i-1][p].r<it.l; p++);
for(; p<LY[i-1].size() && LY[i-1][p].l<=it.r; p++)
{
int u=LY[i-1][p].p, v=it.p;
TY.adj[u].push_back(v);
TY.adj[v].push_back(u);
//printf("adjY %d %d\n", u, v);
}
if(p) p--;
}
}
TX.init(); TY.init();
scanf("%d", &Q);
bool flag=false;
while(Q--)
{
int tt, y, x;
scanf("%d%d%d", &tt, &y, &x);
pii t=get(y, x);
vector<int> V1=TX.getpar(t.first);
vector<int> V2=TY.getpar(t.second);
if(tt==1)
{
for(auto it : V1) for(auto jt : V2)
{
ll pt=((ll)it<<20)|jt;
if(M.find(pt)==M.end()) M[pt]=INF;
M[pt]=min(M[pt], TX.cdist[t.first][TX.cdep[it]]+TY.cdist[t.second][TY.cdep[jt]]);
}
flag=true;
}
else
{
if(!flag) { printf("-1\n"); continue; }
int ans=INF;
for(auto it : V1) for(auto jt : V2)
{
ll pt=((ll)it<<20)|jt;
if(M.find(pt)==M.end()) continue;
ans=min(ans, TX.cdist[t.first][TX.cdep[it]]+TY.cdist[t.second][TY.cdep[jt]]+M[pt]);
}
if(ans==INF) ans=-1;
//if(ans!=-1) assert(flag);
printf("%d\n", ans);
}
}
}
Compilation message (stderr)
C.cpp: In function 'int main()':
C.cpp:144:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
144 | for(int j=0; j+1<X[i].size(); j++)
| ~~~^~~~~~~~~~~~
C.cpp:163:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Line>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
163 | for(; p<LX[i-1].size() && LX[i-1][p].r<it.l; p++);
| ~^~~~~~~~~~~~~~~
C.cpp:164:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Line>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
164 | for(; p<LX[i-1].size() && LX[i-1][p].l<=it.r; p++)
| ~^~~~~~~~~~~~~~~
C.cpp:181:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
181 | for(int j=0; j+1<Y[i].size(); j++)
| ~~~^~~~~~~~~~~~
C.cpp:200:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Line>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
200 | for(; p<LY[i-1].size() && LY[i-1][p].r<it.l; p++);
| ~^~~~~~~~~~~~~~~
C.cpp:201:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Line>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
201 | for(; p<LY[i-1].size() && LY[i-1][p].l<=it.r; p++)
| ~^~~~~~~~~~~~~~~
C.cpp:127:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
127 | scanf("%d", &N);
| ~~~~~^~~~~~~~~~
C.cpp:132:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
132 | scanf("%d%d", &y, &x);
| ~~~~~^~~~~~~~~~~~~~~~
C.cpp:214:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
214 | scanf("%d", &Q);
| ~~~~~^~~~~~~~~~
C.cpp:219:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
219 | scanf("%d%d%d", &tt, &y, &x);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |