[HNOI/AHOI2018]游戏
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;
}