zoukankan      html  css  js  c++  java
  • 解题: SDOI 2011 染色

    题面

    强行把序列问题通过树剖套在树上。。。算了算是回顾了一下树剖的思想=。=

    每次树上跳的时候注意跳的同时维护当前拼出来的左右两条链的靠上的端点,然后拼起来的时候讨论一下拼接点,最后一下左右两边的端点都要考虑

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 const int N=100005;
      6 struct a
      7 {
      8     int cnt;
      9     int lc,rc;
     10 };
     11 int num[N],nmb[N],val[4*N],lcol[4*N],rcol[4*N],laz[4*N];
     12 int siz[N],dep[N],anc[N],imp[N],top[N],dfn[N];
     13 int p[N],noww[2*N],goal[2*N];
     14 int n,m,t1,t2,t3,cnt,tot;
     15 char rd[2];
     16 void link(int f,int t)
     17 {
     18     noww[++cnt]=p[f];
     19     goal[cnt]=t,p[f]=cnt;
     20 }
     21 void DFS(int nde,int fth,int dth)
     22 {
     23     int tmp=0;
     24     siz[nde]=1,anc[nde]=fth,dep[nde]=dth;
     25     for(int i=p[nde];i;i=noww[i])
     26         if(goal[i]!=fth)
     27         {
     28             DFS(goal[i],nde,dth+1);
     29             siz[nde]+=siz[goal[i]];
     30             if(siz[goal[i]]>tmp)
     31                 tmp=siz[goal[i]],imp[nde]=goal[i];
     32         }
     33 }
     34 void MARK(int nde,int tpp)
     35 {
     36     dfn[nde]=++tot,nmb[tot]=num[nde],top[nde]=tpp;
     37     if(imp[nde])
     38     {
     39         MARK(imp[nde],tpp);
     40         for(int i=p[nde];i;i=noww[i])
     41             if(goal[i]!=anc[nde]&&goal[i]!=imp[nde])
     42                 MARK(goal[i],goal[i]);
     43     }
     44 }
     45 void pushup(int nde)
     46 {
     47     int ls=2*nde,rs=2*nde+1;
     48     lcol[nde]=lcol[ls],rcol[nde]=rcol[rs];
     49     val[nde]=val[ls]+val[rs]-(rcol[ls]==lcol[rs]);
     50 }
     51 void create(int nde,int l,int r)
     52 {
     53     if(l==r)
     54         val[nde]=1,lcol[nde]=rcol[nde]=nmb[l];
     55     else
     56     {
     57         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
     58         create(ls,l,mid),create(rs,mid+1,r);
     59         pushup(nde);
     60     }
     61 }
     62 void release(int nde,int l,int r)
     63 {
     64     if(laz[nde])
     65     {
     66         int ls=2*nde,rs=2*nde+1;
     67         laz[ls]=lcol[ls]=rcol[ls]=laz[nde];
     68         laz[rs]=lcol[rs]=rcol[rs]=laz[nde];
     69         val[ls]=val[rs]=1; laz[nde]=0;
     70     }
     71 }
     72 void change(int nde,int l,int r,int nl,int nr,int task)
     73 {
     74     if(l>nr||r<nl)
     75         return ;
     76     else if(l>=nl&&r<=nr)
     77         val[nde]=1,lcol[nde]=rcol[nde]=laz[nde]=task;
     78     else
     79     {
     80         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
     81         change(ls,l,mid,nl,nr,task),change(rs,mid+1,r,nl,nr,task);
     82         pushup(nde);
     83     }    
     84 }
     85 a query(int nde,int l,int r,int nl,int nr)
     86 {
     87     if(l>=nl&&r<=nr)
     88         return (a){val[nde],lcol[nde],rcol[nde]};
     89     else
     90     {
     91         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r); 
     92         if(nr<=mid) return query(ls,l,mid,nl,nr);
     93         if(nl>mid) return query(rs,mid+1,r,nl,nr);
     94         a r1=query(ls,l,mid,nl,nr),r2=query(rs,mid+1,r,nl,nr),ret;
     95         ret.lc=r1.lc,ret.rc=r2.rc,ret.cnt=r1.cnt+r2.cnt-(r1.rc==r2.lc);
     96         return ret;
     97     }    
     98 }
     99 void path_change(int x,int y,int v)
    100 {
    101     while(top[x]!=top[y])
    102     {
    103         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    104         change(1,1,n,dfn[top[x]],dfn[x],v); x=anc[top[x]];
    105     }
    106     if(dep[x]>dep[y]) swap(x,y);
    107     change(1,1,n,dfn[x],dfn[y],v); return ;
    108 }
    109 int path_query(int x,int y)
    110 {
    111     int rt=0,ll=-1,rr=-1;
    112     while(top[x]!=top[y])
    113     {
    114         if(dep[top[x]]<dep[top[y]]) swap(x,y),swap(ll,rr);
    115         a ret=query(1,1,n,dfn[top[x]],dfn[x]); x=anc[top[x]];
    116         rt+=ret.cnt-(ll==ret.rc); ll=ret.lc;
    117     }
    118     if(dep[x]>dep[y]) swap(x,y),swap(ll,rr);
    119     a ret=query(1,1,n,dfn[x],dfn[y]); rt+=ret.cnt-(ll==ret.lc)-(rr==ret.rc); 
    120     return rt;
    121 }
    122 int main ()
    123 {
    124     scanf("%d%d",&n,&m);
    125     for(int i=1;i<=n;i++)
    126         scanf("%d",&num[i]);
    127     for(int i=1;i<n;i++)    
    128         scanf("%d%d",&t1,&t2),link(t1,t2),link(t2,t1);
    129     DFS(1,0,1); MARK(1,1); create(1,1,n);
    130     while(m--)
    131     {
    132         scanf("%s",rd);
    133         if(rd[0]=='C')
    134             scanf("%d%d%d",&t1,&t2,&t3),path_change(t1,t2,t3);
    135         else 
    136             scanf("%d%d",&t1,&t2),printf("%d
    ",path_query(t1,t2));
    137     }
    138     return 0;
    139 }
    View Code
  • 相关阅读:
    (转)上海驾照到期换证流程及注意事项
    sql 获取批处理信息的脚本(优化器在处理批处理时所发生的优化器事件)
    C# xml通过xslt转换为html输出
    C#基础 继承和实例化
    sqlserver 获取数据库、表和字段相关信息
    Json反序列化为动态类型(dynamic)
    Aspose.cells常用用法1
    C# 生成缩略图 去除图片旋转角度
    C# 压缩图片到指定宽度,假如图片小于指定宽度 判断图片大小是否大于指定大小(KB) 如果大于则压缩图片质量 宽高不变
    C# 2个List<T>比较内部项是否相等
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9743416.html
Copyright © 2011-2022 走看看