zoukankan      html  css  js  c++  java
  • [SDOI2011]染色

    题目描述

    输入输出格式

    输入格式:

    输出格式:

    对于每个询问操作,输出一行答案。

    输入输出样例

    输入样例#1:
    6 5
    2 2 1 2 1 1
    1 2
    1 3
    2 4
    2 5
    2 6
    Q 3 5
    C 2 1 1
    Q 3 5
    C 5 1 2
    Q 3 5
    
    输出样例#1:
    3
    1
    2
    

    说明

    题解:

    线段树+树链划分

    先将树拆成链,在用线段树维护区间的答案

    难点就是怎么维护,还有一个问题如下:

    树上的路径可能有多条线段构成,就算维护了区间的答案,还要把那些线段合并

    维护方法,lx表示当前线段的左边颜色,rx同理,合并线段时,如果lson的rx=rson的lx则sum-1

    每次查询完路径的一个树链后,判断链的上端点和其父节点的颜色,若相同,则ans-1

    修改用lazy标记就行

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 struct Node
      7 {
      8     int next,to;
      9 }edge[200001];
     10 int head[100001],num,son[100001],size[100001],s[400001],lx[400001],rx[400001],pos[100001];
     11 int top[100001],fa[100001],dep[100001],tot,sgm[100001],color[100001],lazy[400001],n,m;
     12 char get_op()
     13 {
     14     char ch=getchar();
     15     while (ch!='C'&&ch!='Q') ch=getchar();
     16     return ch;
     17 }
     18 void add(int u,int v)
     19 {
     20     num++;
     21     edge[num].next=head[u];
     22     head[u]=num;
     23     edge[num].to=v;
     24 }
     25 void dfs1(int u,int pa)
     26 {int i;
     27     size[u]=1;
     28     dep[u]=dep[pa]+1;
     29     fa[u]=pa;
     30     for(int i=head[u]; i; i=edge[i].next)
     31     {
     32         int v=edge[i].to;
     33         if(v==pa)continue;
     34         dfs1(v,u);
     35         size[u]+=size[v];
     36         if(size[v]>size[son[u]])son[u]=v;
     37     }
     38 }
     39 void dfs2(int u,int pa,int tp)
     40 {int i;
     41     pos[u]=++tot;
     42     sgm[tot]=u;
     43     top[u]=tp;
     44     if(son[u]) dfs2(son[u],u,tp);
     45     for(int i=head[u]; i; i=edge[i].next)
     46     {
     47         int v=edge[i].to;
     48         if(v==pa||v==son[u])continue;
     49         dfs2(v,u,v);
     50     }
     51 }
     52 void pushdown(int rt)
     53 {
     54     if (lazy[rt]!=-1)
     55     {
     56         lazy[rt*2]=lazy[rt];
     57         lazy[rt*2+1]=lazy[rt];
     58         lx[rt*2]=lx[rt*2+1]=rx[rt*2]=rx[rt*2+1]=lazy[rt];
     59         s[rt*2+1]=s[rt*2]=1;
     60         lazy[rt]=-1;
     61     }
     62 }
     63 void pushup(int rt)
     64 {
     65      lx[rt]=lx[rt*2];
     66      rx[rt]=rx[rt*2+1]; 
     67      s[rt]=s[rt*2]+s[rt*2+1];
     68     if (lx[rt*2+1]==rx[rt*2]) s[rt]--;
     69 }
     70 void build(int rt,int l,int r)
     71 {lazy[rt]=-1;
     72     if (l==r)
     73     {
     74         s[rt]=1;
     75         lx[rt]=rx[rt]=color[sgm[l]];
     76         //cout<<sgm[l]<<' '<<l<<endl;
     77         return;
     78     }
     79      int mid=(l+r)/2;
     80      build(rt*2,l,mid);
     81      build(rt*2+1,mid+1,r);
     82      pushup(rt);
     83 }
     84 int query(int rt,int l,int r,int L,int R)
     85 {int ans=0;
     86     if (l==L&&r==R)
     87     {
     88         return s[rt];
     89     }
     90     pushdown(rt);
     91     int mid=(l+r)/2;
     92      if (L>mid) return query(rt*2+1,mid+1,r,L,R);
     93      else if (R<=mid) return query(rt*2,l,mid,L,R);
     94      else 
     95      {
     96          ans=query(rt*2,l,mid,L,mid)+query(rt*2+1,mid+1,r,mid+1,R);
     97           if (lx[rt*2+1]==rx[rt*2]) ans--;
     98           return ans;
     99       } 
    100 }
    101 void update(int rt,int l,int r,int L,int R,int d)
    102 {
    103     if (l==L&&r==R)
    104     {
    105         s[rt]=1;
    106         lx[rt]=rx[rt]=d;
    107         lazy[rt]=d;
    108         return;
    109     }
    110     pushdown(rt);
    111     int mid=(l+r)/2;
    112     if(L>mid)update(rt*2+1,mid+1,r,L,R,d);
    113     else if(R<=mid)update(rt*2,l,mid,L,R,d);
    114     else update(rt*2,l,mid,L,mid,d),update(rt*2+1,mid+1,r,mid+1,R,d);
    115     pushup(rt);
    116 }
    117 void change(int x,int y,int d)
    118 {
    119      while (top[x]!=top[y])
    120     {
    121         if (dep[top[x]]<dep[top[y]]) swap(x,y);
    122         update(1,1,tot,pos[top[x]],pos[x],d);
    123         x=fa[top[x]];
    124     }
    125     if (dep[x]>dep[y]) swap(x,y);
    126      update(1,1,tot,pos[x],pos[y],d);
    127 }
    128 int query_color(int rt,int l,int r,int x)
    129 {
    130     if (l==r)
    131     {
    132         return lx[rt];
    133     }
    134     pushdown(rt);
    135     int mid=(l+r)/2;
    136      if (x<=mid) return query_color(rt*2,l,mid,x);
    137      else return query_color(rt*2+1,mid+1,r,x);
    138 }
    139 int ask(int x,int y)
    140 {
    141     int ans=0;
    142      while (top[x]!=top[y])
    143     {
    144         if (dep[top[x]]<dep[top[y]]) swap(x,y);
    145         ans+=query(1,1,tot,pos[top[x]],pos[x]);
    146         int p1=query_color(1,1,tot,pos[top[x]]);
    147         int p2=query_color(1,1,tot,pos[fa[top[x]]]);
    148         //cout<<x<<' '<<y<<' '<<ans<<endl;
    149         x=fa[top[x]];
    150         if (p1==p2) ans--;
    151     }
    152     if (dep[x]>dep[y]) swap(x,y);
    153     ans+=query(1,1,tot,pos[x],pos[y]);
    154     if (ans==0) return 1;
    155 return ans;
    156 }
    157 int main()
    158 {int i,j,x,y,c;
    159 char opt;
    160     cin>>n>>m;
    161     memset(lazy,-1,sizeof(lazy));
    162     for (i=1;i<=n;i++)
    163     {
    164         scanf("%d",&color[i]);
    165     }
    166      for (i=1;i<=n-1;i++)
    167      {
    168          scanf("%d%d",&x,&y);
    169          add(x,y);
    170          add(y,x);
    171      }
    172      dfs1(1,1);
    173      dfs2(1,1,1);
    174      build(1,1,tot);
    175      for (i=1;i<=m;i++)
    176      {
    177          opt=get_op();
    178          if (opt=='Q')
    179          {
    180              scanf("%d%d",&x,&y);
    181              printf("%d
    ",ask(x,y));
    182         }
    183         else 
    184         {
    185             scanf("%d%d",&x,&y,&c);
    186             change(x,y,c);
    187         }
    188      }
    189 }
  • 相关阅读:
    MySQL执行外部sql脚本文件的命令
    如何修改mysql 默认引擎为InnoDB?
    最新版的 vscode 怎么配置 Python?
    Go 后端主要做什么
    Go 语言 fmt.Sprintf (格式化输出)
    什么是弱类型语言、强类型语言?
    一个项目从立项到发布的流程
    工厂模式
    观察模式
    类之间的关系
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7214245.html
Copyright © 2011-2022 走看看