[HNOI/AHOI2018]游戏

题目链接

https://loj.ac/problem/2508
https://www.lydsy.com/JudgeOnline/problem.php?id=5288
https://www.luogu.org/problemnew/show/P4436

思路

离散化没啥好说的
一堵墙
左边是i,右边是i+1
如果钥匙在墙的左边,那么右边永远过不去左边(拿不到钥匙)
那就右边向左边连边
就是先处理左边,等全部处理完了再去处理右边
然后拓扑上面暴力弄就好了
听着好像分治呀

吐槽

不过这数据好垃圾呀,随机处理也可以过
我写错了代码还90、、、

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+7;
int read() {
	int x=0,f=1;char s=getchar();
	for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
	for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
	return x*f;
}
int n,js,m,p,hav[N],belong[N],wall[N],L[N],R[N],ru[N],q[N];
struct node {
	int v,nxt;
}e[N];
int head[N],tot;
inline void add(int u,int v) {
	// cout<<u<<" "<<v<<" !\n";
	e[++tot].v=v;
	e[tot].nxt=head[u];
	head[u]=tot;
}
inline int max(int a,int b) {return a>b?a:b;}
inline int min(int a,int b) {return a>b?b:a;}
int main() {
	// freopen("game8.in","r",stdin);
	// freopen("a.out","w",stdout);
	n=read(),m=read(),p=read();
	for(int i=1;i<=m;++i) hav[read()]=read();
	js=1;
	for(int i=1,l=1,r=1;i<=n;++i) {
		belong[i]=js;
		if(hav[i]) js++;
	}
	js=belong[n];
	for(int i=1;i<=n;++i) {
		if(hav[i]) {
			wall[belong[i]]=belong[hav[i]];
			if(hav[i]>i) add(belong[i],belong[i+1]),ru[belong[i+1]]++;
			else add(belong[i+1],belong[i]),ru[belong[i]]++;
			// cout<<x<<" "<<y<<"<\n";
		}
	}
	for(int i=1;i<=js;++i) {
		L[i]=R[i]=i;
		if(!ru[i]) q[++q[0]]=i;
	}
	int mmp=0;
	while(q[0]) {
		int u=q[q[0]];
		q[0]--;
		// cout<<u<<"  <<<<<<u\n";
		for(int i=head[u];i;i=e[i].nxt) {
			int v=e[i].v;
			// cout<<u<<" -> " <<v<<"\n";
        	ru[v]--;
        	while (233) {
				int flag=true;
            	while (L[v] <= wall[R[v]] && wall[R[v]] <= R[v] && R[v]<=js) {
            		flag=false;
            		L[v]=min(L[v],L[R[v]+1]);
            		R[v]=max(R[v],R[R[v]+1]);
				}
            	while (L[v] <= wall[L[v] - 1] && wall[L[v] - 1] <= R[v] && L[v] > 1) {
            		flag=false;
            		L[v]=min(L[v],L[L[v]-1]);
            		R[v]=max(R[v],R[L[v]-1]);
				}
				if(flag) break;
        	}
        	if(!ru[v]) q[++q[0]]=v;
		}
	}
	// for(int i=1;i<=js;++i) cout<<L[i]<<" "<<R[i]<<"<\n";
	for(int i=1;i<=p;++i) {
		int S=read(),T=read();
		if(L[belong[S]]<=belong[T]&&belong[T]<=R[belong[S]]) puts("YES");
		else puts("NO");
	}
	return 0;
}
posted @ 2019-02-24 11:00  ComplexPug  阅读(191)  评论(0编辑  收藏  举报