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 狼人的主要内容,如果未能解决你的问题,请参考以下文章

[IOI 2018] Werewolf

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

[IOI2018]werewolf狼人——kruskal重构树+可持久化线段树

[IOI2018] werewolf 狼人 - 解题报告

[IOI2018] werewolf 狼人 - 解题报告

Luogu4899 IOI2018 Werewolf 主席树Kruskal重构树