题意:给一个无向图和一些询问$(S,E,L,R)$,问能否实现:从$S$出发,经过一些编号$\geq L$的节点后再通过编号$\leq R$的节点到达$E$

先对每条边$(x,y)$以$\max(x,y)$的边权构建最小生成树的kruskal重构树,那么$\leq R$的限制转为在子树内,再以$\min(x,y)$的边权构建最大生成树的kruskal重构树,那么$\geq L$的限制同样转为在子树内,问题变为:求两棵树的两个子树中是否含有编号相同的节点

dfs一遍,每个节点以第一棵树的dfs序为横坐标,以第二棵树的dfs序为纵坐标,那么询问就是矩形数点,直接用可持久化线段树就可以了

#include"werewolf.h"
#include<vector>
#include<algorithm>
using namespace std;
struct pr{
	int x,y;
	pr(int a=0,int b=0){x=a;y=b;}
}e[400010],p[400010];
bool operator<(pr a,pr b){return a.x<b.x;}
bool cmp1(pr a,pr b){return max(a.x,a.y)<max(b.x,b.y);}
bool cmp2(pr a,pr b){return min(a.x,a.y)>min(b.x,b.y);}
int sfa[400010];
int get(int x){return x==sfa[x]?x:(sfa[x]=get(sfa[x]));}
struct tree{
	int h[400010],nex[400010],to[400010],M,n;
	void add(int a,int b){
		M++;
		to[M]=b;
		nex[M]=h[a];
		h[a]=M;
	}
	int fa[400010][19],val[400010],in[400010],ou[400010],p[400010];
	void dfs(int x){
		in[x]=++M;
		p[M]=val[x];
		for(int i=h[x];i;i=nex[i]){
			fa[to[i]][0]=x;
			dfs(to[i]);
		}
		ou[x]=M;
	}
	void gao(){
		int i,j;
		M=0;
		dfs(n);
		for(j=1;j<19;j++){
			for(i=1;i<=n;i++)fa[i][j]=fa[fa[i][j-1]][j-1];
		}
	}
	int geq(int x,int v){
		if(val[x]<v)return 0;
		for(int i=18;i>=0;i--){
			if(fa[x][i]&&val[fa[x][i]]>=v)x=fa[x][i];
		}
		return x;
	}
	int leq(int x,int v){
		if(val[x]>v)return 0;
		for(int i=18;i>=0;i--){
			if(fa[x][i]&&val[fa[x][i]]<=v)x=fa[x][i];
		}
		return x;
	}
}t1,t2;
struct seg{
	int l,r,s;
}t[8000010];
int rt[400010],M;
void insert(int pr,int&nr,int p,int l,int r){
	nr=++M;
	t[nr]=t[pr];
	t[nr].s++;
	if(l==r)return;
	int mid=(l+r)>>1;
	if(p<=mid)
		insert(t[pr].l,t[nr].l,p,l,mid);
	else
		insert(t[pr].r,t[nr].r,p,mid+1,r);
}
int query(int L,int R,int l,int r,int x){
	if(x==0)return 0;
	if(L<=l&&r<=R)return t[x].s;
	int mid=(l+r)>>1,s=0;
	if(L<=mid)s+=query(L,R,l,mid,t[x].l);
	if(mid<R)s+=query(L,R,mid+1,r,t[x].r);
	return s;
}
int N;
int query(int x,int y,int L,int R){
	return query(L,R,1,N,rt[y])-query(L,R,1,N,rt[x-1]);
}
vector<int>check_validity(int n,vector<int>X,vector<int>Y,vector<int>S,vector<int>E,vector<int>L,vector<int>R){
	int m,q,i,j,x,y;
	m=X.size();
	q=S.size();
	for(i=0;i<m;i++)e[i+1]=pr(X[i]+1,Y[i]+1);
	sort(e+1,e+m+1,cmp1);
	for(i=1;i<n*2;i++)sfa[i]=i;
	for(i=1;i<=n;i++)t1.val[i]=i;
	N=n;
	for(i=1;i<=m;i++){
		x=get(e[i].x);
		y=get(e[i].y);
		if(x!=y){
			N++;
			t1.add(N,x);
			t1.add(N,y);
			t1.val[N]=max(t1.val[x],t1.val[y]);
			sfa[x]=sfa[y]=N;
		}
	}
	t1.n=N;
	t1.gao();
	sort(e+1,e+m+1,cmp2);
	for(i=1;i<n*2;i++)sfa[i]=i;
	for(i=1;i<=n;i++)t2.val[i]=i;
	N=n;
	for(i=1;i<=m;i++){
		x=get(e[i].x);
		y=get(e[i].y);
		if(x!=y){
			N++;
			t2.add(N,x);
			t2.add(N,y);
			t2.val[N]=min(t2.val[x],t2.val[y]);
			sfa[x]=sfa[y]=N;
		}
	}
	t2.n=N;
	t2.gao();
	for(i=1;i<=n;i++)p[i]=pr(t1.in[i],t2.in[i]);
	sort(p+1,p+n+1);
	for(i=1;i<=n;i++){
		for(j=p[i-1].x+1;j<=p[i].x;j++)rt[j]=rt[j-1];
		insert(rt[p[i].x],rt[p[i].x],p[i].y,1,N);
	}
	vector<int>ans(q);
	for(i=0;i<q;i++){
		x=t2.geq(S[i]+1,L[i]+1);
		y=t1.leq(E[i]+1,R[i]+1);
		ans[i]=query(t1.in[y],t1.ou[y],t2.in[x],t2.ou[x])?1:0;
	}
	return ans;
}

[UOJ407]Werewolf的更多相关文章

  1. WereWolf项目 Postmortem

    WereWolf项目 Postmortem (博客园的MarkDown编辑器好像有些问题,编号都显示1..) 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描 ...

  2. Werewolf流程分析

    werewolf大致流程 首先是房主创建房间,创建成功以后房主开启web socket连接. 其他成员加入房间,加入房间后新成员和老成员的游戏玩家列表都会更新,然后新成员也要开启web socket连 ...

  3. ural 1242. Werewolf

    1242. Werewolf Time limit: 1.0 secondMemory limit: 64 MB   Knife. Moonlit night. Rotten stump with a ...

  4. URAL 1242 Werewolf(DFS)

    Werewolf Time limit: 1.0 secondMemory limit: 64 MB Knife. Moonlit night. Rotten stump with a short b ...

  5. PAT 1148 Werewolf - Simple Version

    1148 Werewolf - Simple Version (20 分)   Werewolf(狼人杀) is a game in which the players are partitioned ...

  6. PAT A1148 Werewolf - Simple Version (20 分)——暴力遍历,负负得正

    Werewolf(狼人杀) is a game in which the players are partitioned into two parties: the werewolves and th ...

  7. [IOI2018] werewolf 狼人

    [IOI2018] werewolf 狼人 IOI2018题解 (其实原题强制在线,要用主席树) 代码: 注意: 1.下标从0~n-1 2.kruskal重构树开始有n个节点,tot从n开始,++to ...

  8. [IOI2018] werewolf 狼人 kruskal重构树,主席树

    [IOI2018] werewolf 狼人 LG传送门 kruskal重构树好题. 日常安利博客文章 这题需要搞两棵重构树出来,这两棵重构树和我们平时见过的重构树有点不同(据说叫做点权重构树?),根据 ...

  9. uoj407 【IOI2018】狼人

    link 题意: 给一张n个点m条边的无向图,有q个询问,每次询问给出s,t,l,r,问你能否从s走到t,并且初始为人形,结束时必须为狼形,你是人形的时候必须避开$[1,l)$的节点,狼形的时候必须避 ...

随机推荐

  1. react-native中使用Echarts,自己使用WebView封装Echarts经验

    1.工作中遇到的问题 我们在使用react-native肯定遇到过各种奇葩的问题,比如引入Echarts时候莫名报错,但是Echarts官网明显告诉我们可以懒加载的,这是因为基本上js大部分原生的组件 ...

  2. 大聊Python----生产消费者模型

    在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式? 在线程世界里,生产者就是生产数 ...

  3. 4、什么是事务?MySQL如何支持事务?

    什么是事务? 事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行.程序和事务是两个不同的概念.一般而言:一段程序中可能包含多个事务.(说白了就是几步的数据库操作 ...

  4. CTF两个经典的文件包含案例

    案例一URL:http://120.24.86.145:8003/代码 <?php include "waf.php"; include "flag.php&quo ...

  5. MFC单文档框架分析及执行流程(转)

    原文转自 https://blog.csdn.net/u011619422/article/details/40402705 首先来分析一下MFC单文档类的结构: 它包括如下几个类: CAboutDl ...

  6. selenium===splinter模块和selenium异曲同工

    学习文档: http://splinter.readthedocs.io/en/latest/ 安装以后用它来实现163邮箱的登陆操作:*和selenium一样,splinter同样需要对frame进 ...

  7. webIcon

    webIcon是我在拿别人的模板参考的时候我发现的一个东西,觉得挺不错的一个东西,但是后来发现用webIcon其实我也不知道是好还是不好,因为要用到字体,字体文件其实挺大的,所以当你要的图标不多的时候 ...

  8. Jmeter性能测试示例

    这次成功做了一个jmeter借口性能测试的简单测试示例,分享一下给大家. jmeter作为一个简单的开源工具,基于java的性能测试工具,使用起来很简单. 也可以作为二次开发,复杂的情形可以自己写代码 ...

  9. 我XXXX!!!够了!!!从github拉到dockerhub,再用daocloud加速下载

    史上比较曲折的救国方式了... 先在git hub上申请帐号,导入dockerfile. 然后在docker hub上关联git hub帐号作自动构建. 再用daocloud作加速,将docker i ...

  10. 开始学习NodeJs, javascript, 算法

    我的技术路线是C.C++.C#.PHP,什么都做过,很杂,总想着该怎么继续下去. 最近突然发现了NodeJs,觉得很适合我. 学习环境定在了Ubuntu下,编辑软件选择了WebStorm7. 经过几天 ...