[HNOI/AHOI2018]游戏
题目大意:
$n(n\le10^6)$个房间排成一排,相邻两个房间之间有一扇门。其中一些门上了锁,钥匙在某个给定的房间内。$q(q\le10^6)$次询问,每次询问若一开始在$s$房间,能否到达$t$房间。
思路:
[JOISC2017]細長い屋敷改编题。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 const int N=1e6+1; 12 int pos[N],l[N],r[N],right[N]; 13 int main() { 14 const int n=getint(),m=getint(),q=getint(); 15 for(register int i=0;i<m;i++) { 16 const int x=getint(),y=getint(); 17 pos[x]=y; 18 } 19 for(register int i=n;i;i--) { 20 for(l[i]=right[i]=i;right[i]<n&&(!pos[right[i]]||(i<=pos[right[i]]&&pos[right[i]]<=right[i]));) { 21 right[i]=right[right[i]+1]; 22 } 23 } 24 for(register int i=1;i<=n;i++) { 25 r[i]=right[i]; 26 loop: 27 if(l[i]!=1&&(!pos[l[i]-1]||(l[i]<=pos[l[i]-1]&&pos[l[i]-1]<=r[i]))) { 28 const int j=l[i]-1; 29 l[i]=std::min(l[i],l[j]); 30 r[i]=std::max(r[i],r[j]); 31 goto loop; 32 } 33 if(r[i]!=n&&(!pos[r[i]]||(l[i]<=pos[r[i]]&&pos[r[i]]<=r[i]))) { 34 const int j=r[i]+1; 35 r[i]=std::max(r[i],right[j]); 36 goto loop; 37 } 38 } 39 for(register int i=0;i<q;i++) { 40 const int s=getint(),t=getint(); 41 puts(l[s]<=t&&t<=r[s]?"YES":"NO"); 42 } 43 return 0; 44 }