#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100001;
vector<int> tree(4*(N+5),0);
void update(int idx,int l,int r,int ql,int qr,int x)
{
if(ql>qr) return;
if(l==ql&&r==qr) tree[idx]=x;
else
{
int m=(l+r)/2;
update(2*idx,l,m,ql,min(qr,m),x);
update(2*idx+1,m+1,r,max(ql,m+1),qr,x);
}
}
int query(int idx,int l,int r,int pos)
{
if(l==r) return tree[idx];
int m=(l+r)/2;
if(pos<=m) return max(tree[idx],query(2*idx,l,m,pos));
else return max(tree[idx],query(2*idx+1,m+1,r,pos));
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
vector<array<int,2>> points(n+1,{0,0});
vector<array<int,3>> hot_pos(1,{0,0,0});
int hot_cnt=0;
auto add_hot=[&](int x,int y)->int
{
hot_cnt++;
hot_pos.push_back({x,y,hot_cnt});
return hot_cnt;
};
vector<array<int,4>> point_hots(n+1);
vector<array<int,2>> x_compress,y_compress;
for(int i=1;i<=n;i++)
{
auto &[x,y]=points[i];
cin >> x >> y;
x_compress.push_back({x,i});
y_compress.push_back({y,i});
}
sort(x_compress.begin(),x_compress.end());
sort(y_compress.begin(),y_compress.end());
int hx=0;
int hy=0;
for(int i=0;i<n;i++)
{
if(i>0&&x_compress[i][0]!=x_compress[i-1][0]) hx++;
if(i>0&&y_compress[i][0]!=y_compress[i-1][0]) hy++;
points[x_compress[i][1]][0]=hx;
points[y_compress[i][1]][1]=hy;
}
for(int i=1;i<=n;i++)
{
auto &[x,y]=points[i];
int t=0;
for(int j=0;j<=1;j++) for(int k=0;k<=1;k++) point_hots[i][t++]=add_hot(x+j,y+k);
}
sort(y_compress.begin(),y_compress.end());
int m;
cin >> m;
vector<array<int,2>> walls(m+1,{0,0});
vector<array<int,2>> wall_hots(m+1,{0,0});
for(int i=1;i<=m;i++)
{
auto &[a,b]=walls[i];
cin >> a >> b;
if(points[a]>points[b]) swap(a,b);
if(points[a][0]==points[b][0]) wall_hots[i]={point_hots[a][1],point_hots[a][3]};
else wall_hots[i]={point_hots[a][2],point_hots[a][3]};
}
vector<array<int,2>> vedges;
auto add_edge=[&](int a,int b)
{
vedges.push_back({a,b});
vedges.push_back({b,a});
};
auto process=[&]()
{
//extract edges
fill(tree.begin(),tree.end(),-1);
vector<array<int,2>> prv(N+1,{-1,-1}); //x,hot_id
vector<array<int,4>> events; //x,tp,[y,hot_id] or [yl,yr]
for(int i=1;i<=hot_cnt;i++) events.push_back({hot_pos[i][0],0,hot_pos[i][1],i});
for(int i=1;i<=m;i++)
{
auto [a,b]=walls[i];
auto [xa,ya]=points[a];
auto [xb,yb]=points[b];
if(xa==xb) events.push_back({xa,1,ya+1,yb});
}
sort(events.begin(),events.end());
for(auto [x,tp,yl,yr]:events)
{
if(tp==0)
{
int w=query(1,0,N,yl);
auto [px,pid]=prv[yl];
if(w<px) add_edge(yr,pid);
prv[yl]={x,yr};
}
else update(1,0,N,yl,yr,x);
}
//flip coordinates
for(int i=1;i<=n;i++) swap(points[i][0],points[i][1]);
for(int i=1;i<=hot_cnt;i++) swap(hot_pos[i][0],hot_pos[i][1]);
};
process();
process();
vector<int> cc_id(hot_cnt+1,0);
int cc_cnt=0;
queue<int> q;
sort(vedges.begin(),vedges.end());
vector<int> vedges_start(hot_cnt+1,0);
for(int i=(int)vedges.size()-1;i>=0;i--) vedges_start[vedges[i][0]]=i;
for(int i=1;i<=hot_cnt;i++)
{
if(cc_id[i]!=0) continue;
cc_cnt++;
auto add=[&](int a)
{
if(cc_id[a]==0)
{
cc_id[a]=cc_cnt;
q.push(a);
}
};
add(i);
while(!q.empty())
{
int a=q.front();
q.pop();
for(int j=vedges_start[a];j<(int)vedges.size()&&vedges[j][0]==a;j++) add(vedges[j][1]);
}
}
vedges.clear();
for(int i=1;i<=m;i++)
{
auto [a,b]=wall_hots[i];
vedges.push_back({cc_id[a],cc_id[b]});
vedges.push_back({cc_id[b],cc_id[a]});
}
sort(vedges.begin(),vedges.end());
for(int i=(int)vedges.size()-1;i>=0;i--) vedges_start[vedges[i][0]]=i;
vector<int> d(cc_cnt+1,0);
sort(hot_pos.begin(),hot_pos.end());
auto add=[&](int a,int nd)
{
if(d[a]==0)
{
d[a]=nd;
q.push(a);
}
};
for(auto [x,y,hot]:hot_pos)
{
add(cc_id[hot],1);
while(!q.empty())
{
int a=q.front();
q.pop();
for(int j=vedges_start[a];j<(int)vedges.size()&&vedges[j][0]==a;j++) add(vedges[j][1],d[a]+1);
}
}
vector<int> res;
for(int i=1;i<=m;i++)
{
auto [a,b]=wall_hots[i];
if(d[cc_id[a]]==d[cc_id[b]]) res.push_back(i);
}
cout << res.size() << "\n";
for(int w:res) cout << w << "\n";
return 0;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
2644 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
2644 KB |
Output is correct |
2 |
Correct |
2 ms |
2644 KB |
Output is correct |
3 |
Correct |
2 ms |
2644 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
2644 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
2712 KB |
Output is correct |
2 |
Correct |
4 ms |
2884 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
2644 KB |
Output is correct |
2 |
Correct |
2 ms |
2644 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
2644 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
4 ms |
2800 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
2772 KB |
Output is correct |
2 |
Correct |
4 ms |
2884 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
2772 KB |
Output is correct |
2 |
Correct |
4 ms |
2772 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
106 ms |
11824 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
391 ms |
36128 KB |
Memory limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
407 ms |
37564 KB |
Memory limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
577 ms |
44892 KB |
Memory limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
596 ms |
45460 KB |
Memory limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |