zoukankan      html  css  js  c++  java
  • [cf576E]Painting Edges

    先线段树分治,但事实上与普通的动态连通性/二分图的判定有很大的区别:

    1.对每一个修改(建议将初始的边也作为无色修改),在其第一次修改时进行判定,若发现不合法则将其颜色改为对该边最后一次可行的修改,之后再执行即可;

    2.操作顺序会影响,有可能左子树中的操作先于父亲的操作

    对于此类操作,必然要求父亲之前未被操作(否则没有影响),换言之其左端点恰好为区间左端点

    注意到由于左端点各不相同,因此比其早的操作一定恰好是他的一条左链(左儿子、左儿子的左儿子……)上的所有操作

    具体实现可以记录当前那个不确定是否执行的操作(根据左端点各不相同,是唯一的),在搜索到叶子时再判断,当左儿子返回合法后再执行(注意每一个左儿子返回都要执行)

    时间复杂度为$o(nlog^{2}n+nk)$($n$、$m$、$q$同阶,两个log分别是线段树分治和并查集,$nk$是初始化并查集),可以通过

    (代码有点问题,拍不出来懒得查了,思路yy的感觉没啥问题)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 500005
      4 #define L (k<<1)
      5 #define R (L+1)
      6 #define mid (l+r>>1)
      7 struct ji{
      8     int id,c;
      9 }u[N<<1];
     10 vector<int>v[N<<3];
     11 int n,m,q,un,x[N],y[N],las[N],ans[N<<1];
     12 void update(int k,int l,int r,int x,int y,int z){
     13     if ((l>y)||(x>r))return;
     14     if ((x<=l)&&(r<=y)){
     15         v[k].push_back(z);
     16         return;
     17     }
     18     update(L,l,mid,x,y,z);
     19     update(R,mid+1,r,x,y,z);
     20 }
     21 struct union_find{
     22     int len[N],d[N],sz[N],f[N];
     23     vector<int>v;
     24     void init(){
     25         for(int i=1;i<=n;i++){
     26             f[i]=i;
     27             sz[i]=1;
     28         }
     29     }
     30     int find(int k){
     31         if (k==f[k]){
     32             d[k]=0;
     33             return k;
     34         }
     35         int fa=find(f[k]);
     36         d[k]=(d[f[k]]^len[k]);
     37         return fa;
     38     }
     39     bool add(int x,int y){//0表示产生奇环 
     40         if (find(x)==find(y))return d[x]^d[y];
     41         int p=(d[x]^d[y]);
     42         x=find(x),y=find(y);
     43         if (sz[x]<sz[y])swap(x,y);
     44         v.push_back(y);
     45         f[y]=x;
     46         len[y]=(p^1);
     47         sz[x]+=sz[y];
     48         return 1;
     49     }
     50     void ctrlz(int now){
     51         while (v.size()>now){
     52             int k=v.back();
     53             v.pop_back();
     54             sz[f[k]]-=sz[k];
     55             len[k]=0;
     56             f[k]=k;
     57         }
     58     }
     59 }T[51];
     60 bool check(int k){
     61     int id=u[k].id;
     62     ans[k]=T[u[k].c].add(x[id],y[id]);
     63     if (!u[k].c)ans[k]=1;
     64     if (!ans[k])u[k].c=las[id];
     65     return ans[k];
     66 }
     67 void add(int k){
     68     int id=u[k].id;
     69     T[u[k].c].add(x[id],y[id]);
     70     las[id]=u[k].c;
     71 }
     72 bool dfs(int k,int l,int r,int un){
     73     int flag=0,now[51];
     74     for(int i=0;i<=50;i++)now[i]=T[i].v.size();
     75     for(int i=0;i<v[k].size();i++)
     76         if (ans[v[k][i]]>=0)add(v[k][i]);
     77         else un=v[k][i];
     78     if (l==r){
     79         if (un)flag=check(un); 
     80     }
     81     else{
     82         flag=dfs(L,l,mid,un);
     83         if (flag)add(un);
     84         dfs(R,mid+1,r,0);
     85     }
     86     for(int i=0;i<=50;i++)T[i].ctrlz(now[i]);
     87     return flag;
     88 }
     89 int main(){
     90     scanf("%d%d%*d%d",&n,&m,&q);
     91     for(int i=1;i<=m;i++){
     92         scanf("%d%d",&x[i],&y[i]);
     93         u[i].id=las[i]=i;
     94     }
     95     for(int i=m+1;i<=q+m;i++){
     96         scanf("%d%d",&u[i].id,&u[i].c);
     97         update(1,1,m+q,las[u[i].id],i-1,las[u[i].id]);
     98         las[u[i].id]=i;
     99     }
    100     for(int i=1;i<=m;i++)update(1,1,m+q,las[i],m+q,las[i]);
    101     memset(las,0,sizeof(las));
    102     memset(ans,-1,sizeof(ans));
    103     for(int i=1;i<=m;i++)ans[i]=1;
    104     for(int i=0;i<=50;i++)T[i].init();
    105     dfs(1,1,m+q,0);
    106     for(int i=m+1;i<=m+q;i++)
    107         if (ans[i])printf("YES
    ");
    108         else printf("NO
    ");
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    【java虚拟机】垃圾回收机制详解
    【java虚拟机】分代垃圾回收策略的基础概念
    【java虚拟机】内存分配与回收策略
    【java虚拟机】jvm内存模型
    【转】新说Mysql事务隔离级别
    【转】互联网项目中mysql应该选什么事务隔离级别
    有关PHP的字符串知识
    php的查询数据
    php练习题:投票
    php的数据访问
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14382888.html
Copyright © 2011-2022 走看看