[HNOI2018]遊戲
阿新 • • 發佈:2019-03-23
getc 編號 type 不想 shuff getchar 因此 fine clu
Description:
一次小G和小H在玩尋寶遊戲,有n個房間排成一列,編號為\(1,2,...,n\),相鄰的房間之間都有一道門。其中一部分們上鎖(因此需要有對應的鑰匙才能開門),其余的門都能直接打開。現在小G告訴了小H每把鎖的鑰匙在哪個房間裏(每把鎖鎖有且只有一把鑰匙與之對應),並作出p次指示:第i次讓小H從第\(S_i\)個房間出發到\(T_i\)個房間裏。但是小G有時會故意在指令中放入死路,而小H也不想浪費多余的體力去嘗試,於是想事先調查清楚每次的指令是否會存在一條通路。
Hint:
\(n,m,q \le 10^6\)
Solution:
每次直接在一個點暴力向兩邊拓展,但這樣會被卡,隨機化就行了
(然而不隨機化,就是倒著跑還快一點,數據666)
#include <map> #include <set> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define ls p<<1 #define rs p<<1|1 using namespace std; typedef long long ll; const int mxn=2e6+5; int n,m,q,cnt,hd[mxn]; int a[mxn],b[mxn],L[mxn],R[mxn]; inline int read() { char c=getchar(); int x=0,f=1; while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();} return x*f; } inline void chkmax(int &x,int y) {if(x<y) x=y;} inline void chkmin(int &x,int y) {if(x>y) x=y;} struct ed { int to,nxt; }t[mxn<<1]; inline void add(int u,int v) { t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt; } void expand(int x) { int l=x,r=x; while(1) { int flag=0; if(l>1&&((l<=a[l-1]&&a[l-1]<=r)||!a[l-1])) flag=1,--l,l=min(l,L[l]),r=max(r,R[l]); if(r<n&&((l<=a[r]&&a[r]<=r)||!a[r])) flag=1,++r,l=min(l,L[r]),r=max(r,R[r]); if(!flag) break; } L[x]=l,R[x]=r; } int main() { n=read(); m=read(); q=read(); int x,y; for(int i=1;i<=m;++i) { x=read(); y=read(); a[x]=y; } for(int i=1;i<=n;++i) L[i]=n+1,R[i]=0,b[i]=i; random_shuffle(b+1,b+n+1); for(int i=1;i<=n;++i) expand(b[i]); while(q--) { x=read(); y=read(); if(L[x]<=y&&y<=R[x]) puts("YES"); else puts("NO"); } return 0; }
[HNOI2018]遊戲