[cf1642E]Anonymity Is Important
Description
q次在线操作,实时告诉区间[l,r]有/没有病人,询问病人x是否一定患病/无病。
Solution
用时间戳在线转离线。
一个病人无病当且仅当他属于某个无病区间。
一个病人一定有病当且仅当他在某个除了他都没病的有病区间内。
否则不确定是否有病。
可以发现,有病区间互不干扰。
只需先处理出无病的病人,记录他们最早被确定无病的时间。
再对于每个有病区间求是否只有一个病人可能有病,记录病人最早被确定有病的时间。
对于每个询问,只要晚于最早被确定有/无病的时间,就可以确定,否则为不确定。
处理方法一
用线段树记录每个区间是否全为有病/除了一个外其余全都有病,记录每个区间的时间戳最大值。
处理方法二
用set记录可能有病的病人。
依次删去无病区间的点,记录他们最早被确定无病的时间。
再对每个有病区间求区间内是否存在第二个可能有病的人,更新病人最早被确定有病的时间。
#include<bits/stdc++.h> using namespace std; const int N=200005,M=800005; struct patient{ int ty;//1:YES,sick; 0:N/A:0; -1,NO.not sick int t; }ans[N]; struct SegmentTree{ int t; }lt[M]; struct update{ int l,r,t; }ud1[N],ud2[N]; struct query{ int x,t; }q[N]; int n,m,m1,m2,t; set<int> s; void build(int u,int l,int r){ if(l==r){ lt[u].t=ans[l].t; return; } int mid=(l+r)>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); lt[u].t=max(lt[u<<1].t,lt[u<<1|1].t); } int ask(int u,int lef,int rig,int l,int r){ if(l<=lef&&rig<=r) return lt[u].t; int ret=0,mid=(lef+rig)>>1; if(l<=mid) ret=max(ret,ask(u<<1,lef,mid,l,r)); if(r>mid) ret=max(ret,ask(u<<1|1,mid+1,rig,l,r)); return ret; } int main(){ scanf("%d%d",&n,&t); for(int i=1,ty,l,r,x;i<=t;++i){ scanf("%d",&ty); if(ty){ scanf("%d",&x); q[++m]=(query){x,i}; } else{ scanf("%d%d%d",&l,&r,&x); if(x) ud1[++m1]=(update){l,r,i}; else ud2[++m2]=(update){l,r,i}; } } for(int i=1;i<=n;++i) s.insert(i); for(int i=1;i<=m2;++i){ set<int>::iterator u=s.lower_bound(ud2[i].l); while(u!=s.end()&&(*u)<=ud2[i].r){ ans[*u]=(patient){-1,ud2[i].t}; s.erase(u++); } } build(1,1,n); for(int i=1;i<=m1;++i){ if(ud1[i].l==ud1[i].r){ if(!ans[ud1[i].l].ty||ud1[i].t<ans[ud1[i].l].t) ans[ud1[i].l]=(patient){1,ud1[i].t}; continue; } set<int>::iterator u1=s.lower_bound(ud1[i].l); if(u1==s.end()) continue; set<int>::iterator u2=u1;++u2; if((*u1)<=ud1[i].r&&(u2==s.end()||(*u2)>ud1[i].r)){ int t=max(ud1[i].t,ask(1,1,n,ud1[i].l,ud1[i].r)); if(!ans[*u1].ty||t<ans[*u1].t) ans[*u1]=(patient){1,t}; } } for(int i=1;i<=m;++i){ if(!ans[q[i].x].ty||ans[q[i].x].t>q[i].t) printf("N/A\n"); else if(ans[q[i].x].ty>0) printf("YES\n"); else printf("NO\n"); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现