2 条题解
-
0
分析
首先想到的一个优化就是考虑去掉一些没用的点。怎么做呢?
我们可以把满足:
- 在所有点中出现次数 。
- 没有访问过。
这些条件的点存储起来,构造集合 ,查询时只需要找这些点。
证明
现在我们要证明:若 ,对于任意一个 , 中存在 ,满足 。
设 。
设 。
根据定义,,所以 。
所以必定存在。
对于 :
如果有解,必然 ,在 中。
如果无解,必然不存在 , 中不存在。
解释
解释为什么限制 的出现为 不是 :
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; }
信息
- ID
- 210
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 4
- 标签
- 递交数
- 115
- 已通过
- 12
- 上传者