p4899 [IOI2018] werewolf 狼人
Posted yzxverygood
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了p4899 [IOI2018] werewolf 狼人相关的知识,希望对你有一定的参考价值。
分析
我用的主席树维护qwq
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
struct node {
int le,ri,sum;
};
node d[400005*35];
int n,m,q,val[400005],rt[400005],cnt;
vector<int>v[400005];
struct Tree {
int kk,dfn[400005],fin[400005],fa[400005],pa[400005][21],T;
vector<int>vv[400005];
inline int sf(int x){return fa[x]==x?x:fa[x]=sf(fa[x]);}
inline void dfs(int x){
dfn[x]=++T;
for(int i=1;i<20;i++)pa[x][i]=pa[pa[x][i-1]][i-1];
for(int i=0;i<vv[x].size();i++)dfs(vv[x][i]);
fin[x]=T;
}
inline void work(){
int i,j,k;
for(i=1;i<=n;i++)fa[i]=i;
if(kk){
for(i=n;i;i--)
for(j=0;j<v[i].size();j++)
if(i<v[i][j]){
k=sf(v[i][j]);
if(k==i)continue;
vv[i].push_back(k);
fa[k]=pa[k][0]=i;
}
dfs(1);
}else {
for(i=1;i<=n;i++)
for(j=0;j<v[i].size();j++)
if(i>v[i][j]){
k=sf(v[i][j]);
if(k==i)continue;
vv[i].push_back(k);
fa[k]=pa[k][0]=i;
}
dfs(n);
}
}
inline int go(int x,int len){
int i,j,k;
for(i=19;i>=0;i--)
if(pa[x][i]&&((kk&&pa[x][i]>=len)||(!kk&&pa[x][i]<=len)))
x=pa[x][i];
return x;
}
};
Tree A,B;
inline void update(int &x,int y,int le,int ri,int k){
d[++cnt]=d[y];
d[cnt].sum++;
x=cnt;
if(le==ri)return;
int mid=(le+ri)>>1;
if(mid>=k)update(d[x].le,d[y].le,le,mid,k);
else update(d[x].ri,d[y].ri,mid+1,ri,k);
}
inline int que(int a,int b,int le,int ri,int x,int y){
if(le>=x&&ri<=y)return d[a].sum-d[b].sum;
int mid=(le+ri)>>1,Ans=0;
if(mid>=x)Ans+=que(d[a].le,d[b].le,le,mid,x,y);
if(mid<y)Ans+=que(d[a].ri,d[b].ri,mid+1,ri,x,y);
return Ans;
}
int main(){
int i,j,k,x,y;
scanf("%d%d%d",&n,&m,&q);
for(i=1;i<=m;i++){
scanf("%d%d",&x,&y);
x++,y++;
v[x].push_back(y);
v[y].push_back(x);
}
A.kk=1;A.work();B.work();
for(i=1;i<=n;i++)val[A.dfn[i]]=B.dfn[i];
for(i=1;i<=n;i++)update(rt[i],rt[i-1],1,n,val[i]);
for(i=1;i<=q;i++){
int s,t,le,ri;
scanf("%d%d%d%d",&s,&t,&le,&ri);
s++,t++,le++,ri++;
s=A.go(s,le),t=B.go(t,ri);
if(que(rt[A.fin[s]],rt[A.dfn[s]-1],1,n,B.dfn[t],B.fin[t]))puts("1");
else puts("0");
}
return 0;
}
以上是关于p4899 [IOI2018] werewolf 狼人的主要内容,如果未能解决你的问题,请参考以下文章
[IOI2018] werewolf 狼人 kruskal重构树,主席树