- P209's solution
-
P209's Solution
- 审核备注:要不你把 P215 也写一下??? @ 2026-1-26 9:19:02
分析
首先想到的一个优化就是考虑去掉一些没用的点。怎么做呢?
我们可以把满足:
- 在所有点中出现次数 。
- 没有访问过。
这些条件的点存储起来,构造集合 ,查询时只需要找这些点。
证明
现在我们要证明:若 ,对于任意一个 , 中存在 ,满足 。
设 。
设 。
根据定义,,所以 。
所以必定存在。
对于 :
如果有解,必然 ,在 中。
如果无解,必然不存在 , 中不存在。
解释
解释为什么限制 的出现为 不是 :
if(mx[qp.x]<=2&&my[qp.y]<=2&&!vis[qp]){
++mx[qp.x];
++my[qp.y];
vis[qp]=1;
p.emplace_back((node){qp,i});
}
这是因为可能存在 个点是被摧毁的,且 ,必须限制为 ,才能找到没有被摧毁的那一个点。
时间复杂度
与 共享 或 坐标的点最多有 个( 相同的最多 个, 相同的最多 个)。
,主要是使用了 map。
//SPJ:???
// #include<bits/stdc++.h>
#include<bits/extc++.h>
#define gp __gnu_pbds::gp_hash_table
#define endl '\n'
#define hh puts("")
//#define int long long
#define uap unordered_map
#define uet unordered_set
#define sr() srand(time(NULL))
#define rando(cntmax,istart,rng) for(int i=istart,cnt=0;cnt<=cntmax;cnt++,i=(rand()%rng))
#define lrfor(l,r) for(int cnt=1,i=l,j=r,forid=i;i<j&&l<=i&&i<=r&&l<=j&&j<=r;i+=cnt%2,j-=cnt%2,forid=(cnt%2?j:i),++cnt)
#define lrfor2(l,r) for(size_t cnt=1,i=l,j=r,forid=i;i<j&&l<=i&&i<=r&&l<=j&&j<=r;i+=cnt%2,j-=cnt%2,forid=(cnt%2?j:i),++cnt)
#define IAKIOI ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,mn,stdin),p1==p2)?EOF:*p1++)
namespace IO{
const int mn=1e6+100;
char buf[mn],*p1=buf,*p2=buf;
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
return x*f;
}
inline void write(int x){
if(x<0){putchar('-');x=-x;}
if(x>9)write(x/10);
putchar(x%10+'0');
}
}using namespace IO;
const int N=1e6+10;
using namespace std;
struct point{
int x,y;
friend inline bool operator<(point aa,point bb){return(aa.x!=bb.x?aa.x<bb.x:aa.y<bb.y);}
// friend inline bool operator==(point aa,point bb){return aa.x==bb.x&&aa.y==bb.y;}
};
struct node{
point dot;
int id;
};
gp<int,int> mx,my;
map<point,bool> vis;
vector<node> p;
inline bool check(point che,point man){
return man.x!=che.x&&man.y!=che.y;
}
signed main(){
int n,q;
n=read();
q=read();
for(int i=1;i<=n;++i){
point qp;
qp.x=read();
qp.y=read();
if(mx[qp.x]<=2&&my[qp.y]<=2&&!vis[qp]){
++mx[qp.x];
++my[qp.y];
vis[qp]=1;
p.emplace_back((node){qp,i});
}
}
while(q--){
point t;
t.x=read();
t.y=read();
bool flag=0;
for(int i=1;i<p.size();i++){
point q=p[i].dot;
if(check(t,q)){
write(p[i].id);
hh;
flag=1;
break;
}
}
if(!flag)write(-1),hh;
}
return 0;
}