• 洛谷3767 膜法 带权并查集+分治


    这么一道题折磨了不知道多久。。。

    本来一直在撕烤可持久化,题解也没有看懂

    思路:

    跑出dfs序,则每条边的作用范围都是两段连续区间,放到线段树上就是2logn个区间

    全都在线段树上挂好

    然后分治,每次往下跑的时候把边加上,往下跑的时候把边删掉(所以不能路径压缩)

    (某dalao写了按秩合并,但是没写也能过,题目不卡)

      1 #include <bits/stdc++.h>
      2 #define MAXN 500000
      3 #define mid (l+r>>1)
      4 using namespace std;
      5 int n,m,top,TIME,X,Y;
      6 int beg[MAXN],en[MAXN],ans[MAXN],fir[MAXN],nex[MAXN];
      7 int fa[MAXN], sz[MAXN], d[MAXN], st[MAXN];
      8 vector<int> O[MAXN],out[MAXN];
      9 struct qry
     10 {
     11     int u,v,cas;
     12 }q[MAXN];
     13 int getfa(int x){return x==fa[x]?x:getfa(fa[x]);}
     14 int getdep(int x){return x==fa[x]?0:(d[x]+getdep(fa[x]))%5;}
     15 bool com(int x,int y)
     16 {
     17     return (beg[x]<beg[y] || (beg[x]==beg[y] && en[x]<en[y]));
     18 }
     19 void dfs(int now)
     20 {
     21     beg[now]=++TIME;
     22     for(int i=fir[now];i;i=nex[i])
     23         dfs(i);
     24     en[now]=TIME;
     25 }
     26 void add(int now,int l,int r,int x,int y,int z)
     27 {
     28     if(l==x&&r==y)
     29     {
     30         O[now].push_back(z);
     31     //    printf("%d %d %d
    ",z,x,y);
     32         return;
     33     }
     34     if(x<=mid)
     35         add(now<<1,l,mid,x,min(mid,y),z);
     36     if(y>mid)
     37         add(now<<1|1,mid+1,r,max(x,mid+1),y,z);
     38 }
     39 void work(int now,int l,int r,int x)
     40 {
     41     if(l==8 && r==8)
     42         int e=1;
     43     bool ok=1;
     44     for(int i=0;i<O[now].size();i++)
     45     {
     46         qry _q=q[O[now][i]];
     47         if(getfa(_q.u)==getfa(_q.v))
     48         {
     49             if((getdep(_q.v)-getdep(_q.u)+5)%5!=_q.cas)
     50             {
     51                 ok=0;
     52                 break;
     53             }
     54         }
     55         else
     56         {
     57             X=getfa(_q.u),Y=getfa(_q.v);
     58             fa[st[++top]=Y]=X,d[Y]=(_q.cas+getdep(_q.u)-getdep(_q.v)+5)%5;
     59         }
     60     }
     61     if(ok)
     62         if(l==r)
     63             ans[l]=1;
     64         else
     65         {
     66             work(now<<1,l,mid,top);
     67             work(now<<1|1,mid+1,r,top);
     68         }
     69     while(top>x)
     70         fa[st[top]]=st[top],d[st[top]]=0,top--;
     71 }
     72 int main()
     73 {
     74     scanf("%d%d",&n,&m);
     75     for(int i=1;i<=m;i++)
     76     {
     77         int tem;
     78         scanf("%d%d",&tem,&q[i].cas);
     79         nex[i]=fir[tem];fir[tem]=i;
     80         if(q[i].cas<=2)
     81             scanf("%d%d",&q[i].u,&q[i].v);
     82         else
     83             scanf("%d",&tem),out[tem].push_back(i);
     84     }
     85     dfs(0);
     86     for(int i=1;i<=m;i++)
     87     if(q[i].cas<=2)
     88     {
     89         sort(out[i].begin(),out[i].end(),com);
     90         for(int j=0;j<=out[i].size();j++)
     91         {
     92             int L=j?en[out[i][j-1]]+1:beg[i];
     93             int R=j<out[i].size()?beg[out[i][j]]-1:en[i];
     94             if(L<=R)
     95             {
     96                 add(1,1,m+1,L,R,i);
     97             }
     98         }
     99     }
    100     for(int i=1;i<=n;i++)
    101         fa[i]=i;
    102     top=0;
    103     work(1,1,m+1,0);
    104     for(int i=1;i<=m;i++)
    105         puts(ans[beg[i]]?"excited":"naive");
    106     return 0;
    107 }
  • 相关阅读:
    VC6.0图形处理7边缘检测
    VC6.0图像处理0bmp文件分析
    java版QQ 欢迎点评
    VC6.0图像处理3灰度变换
    VC6.0图形处理6图像增强
    VC6.0图像处理1浏览图片
    VC6.0图像处理4镜像
    一个软件行业中层主管在年底给团队成员的一封信
    SQL的EXISTS与in、not exists与not in 效率比较和使用
    按某字段合并字符串
  • 原文地址:https://www.cnblogs.com/wanglichao/p/6861451.html
Copyright © 2020-2023  润新知