zoukankan      html  css  js  c++  java
  • LOJ10141染色

    SDOI 2011 染色

    给定一棵有 n 个节点的无根树和 m 个操作,操作共两类。

    将节点 a 到节点 b 路径上的所有节点都染上颜色;

    询问节点 a 到节点 b 路径上的颜色段数量,连续相同颜色的认为是同一段,例如 112221 由三段组成:11 、 222、1。

    请你写一个程序依次完成操作。

    输入格式
    第一行包括两个整数 n,m,表示节点数和操作数;

    第二行包含 n 个正整数表示 n 个节点的初始颜色;

    接下来若干行包含两个整数 x 和 y,表示 x 和 y 之间有一条无向边;

    接下来若干行每行描述一个操作:

    C a b c 表示这是一个染色操作,把节点 a 到节点 b 路径上所有点(包括 a 和 b)染上颜色;

    Q a b 表示这是一个询问操作,把节点 a 到节点 b 路径上(包括 a 和 b)的颜色段数量。

    输出格式
    对于每个询问操作,输出一行询问结果。

    样例
    样例输入
    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
    样例输出
    3
    1
    2
    数据范围与提示
    对于 100% 的数据,N,M≤10^5, 所有颜色 C 为整数且在 [0,10^9] 之间。

    _____________________________________________________________________________________

    树链剖分,需要维护

    sum[]:表示段内的色段数

    lc[]:表示左侧点的颜色

    rc[]:表示右侧点的颜色

    所以,

    sum[cur]=sum[cur<<1]+sum[cur<<1|1]-(rc[cur<<1]==lc[cur<<1|1])

    lc[cur]=lc[cur<<1]

    rc[cur]=rc[cur<<1|1]

    需要注意,树链之间两点的颜色是否相同。

    ———————————————————————————————————————————————

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=1e5+10;
      4 int n,m;
      5 struct edge
      6 {
      7     int u,v,nxt;
      8 }e[maxn<<1];
      9 int head[maxn],js;
     10 void addage(int u,int v)
     11 {
     12     e[++js].u=u;e[js].v=v;
     13     e[js].nxt=head[u];head[u]=js;
     14 }
     15 int w[maxn];
     16 int dep[maxn],fat[maxn],son[maxn],siz[maxn];
     17 void dfs(int u,int fa)
     18 {
     19     dep[u]=dep[fa]+1;
     20     fat[u]=fa;
     21     siz[u]=1;
     22     for(int i=head[u];i;i=e[i].nxt)
     23     {
     24         int v=e[i].v;
     25         if(v==fa)continue;
     26         dfs(v,u);
     27         siz[u]+=siz[v];
     28         if(!son[u] || siz[son[u]]<siz[v])son[u]=v;
     29     }
     30 }
     31 int pos[maxn],fos[maxn],top[maxn],p;
     32 void getpos(int u,int fa)
     33 {
     34     pos[u]=++p;
     35     fos[p]=u;
     36     top[u]=fa;
     37     if(!son[u])return;
     38     getpos(son[u],fa);
     39     for(int i=head[u];i;i=e[i].nxt)
     40     {
     41         int v=e[i].v;
     42         if(v!=fat[u] && v!=son[u])getpos(v,v);
     43     }
     44 }
     45 int sum[maxn<<2],lc[maxn<<2],rc[maxn<<2],delt[maxn<<2];
     46 void update(int cur)
     47 {
     48     lc[cur]=lc[cur<<1];
     49     rc[cur]=rc[cur<<1|1];
     50     sum[cur]=sum[cur<<1]+sum[cur<<1|1]-(rc[cur<<1]==lc[cur<<1|1]);
     51 }
     52 void build(int cur,int l,int r)
     53 {
     54     if(l==r)
     55     {
     56         lc[cur]=rc[cur]=w[fos[l]];
     57         sum[cur]=1;
     58         return;
     59     }
     60     int mid=(l+r)>>1;
     61     build(cur<<1,l,mid);
     62     build(cur<<1|1,mid+1,r);
     63     update(cur);
     64 }
     65 void down(int cur)
     66 {
     67     sum[cur<<1]=sum[cur<<1|1]=1;
     68     delt[cur<<1]=delt[cur<<1|1]=lc[cur<<1]=rc[cur<<1]=lc[cur<<1|1]=rc[cur<<1|1]=delt[cur];
     69     delt[cur]=-1;
     70 }
     71 void modi(int cur,int l,int r,int ql,int qr,int x)
     72 {
     73     if(ql<=l && r<=qr)
     74     {
     75         sum[cur]=1;
     76         delt[cur]=lc[cur]=rc[cur]=x;
     77         return ;
     78     }
     79     int mid=(l+r)>>1;
     80     if(delt[cur]!=-1)down(cur);
     81     if(ql<=mid)modi(cur<<1,l,mid,ql,qr,x);
     82     if(mid<qr)modi(cur<<1|1,mid+1,r,ql,qr,x);
     83     update(cur);
     84 }
     85 void change(int u,int v,int x)
     86 {
     87     int tpu=top[u],tpv=top[v];
     88     while(tpu!=tpv)
     89     {
     90         if(dep[tpu]<dep[tpv])
     91         {
     92             swap(u,v);swap(tpu,tpv);
     93         }
     94         modi(1,1,n,pos[tpu],pos[u],x);
     95         u=fat[tpu];tpu=top[u];
     96     }
     97     if(dep[u]>dep[v])swap(u,v);
     98     modi(1,1,n,pos[u],pos[v],x);
     99 }
    100 int query_c(int cur,int l,int r,int p)
    101 {
    102     if(l==r)return lc[cur];
    103     int mid=(l+r)>>1;
    104     if(delt[cur]!=-1)down(cur);
    105     if(p<=mid)return query_c(cur<<1,l,mid,p);
    106     else return query_c(cur<<1|1,mid+1,r,p);
    107 }
    108 int query(int cur,int l,int r,int ql,int qr)
    109 {
    110     if(ql<=l && r<=qr)return sum[cur];
    111     int mid=(l+r)>>1,ans=0;
    112     if(delt[cur]!=-1)down(cur);
    113     if(ql<=mid)ans+=query(cur<<1,l,mid,ql,qr);
    114     if(qr>mid)ans+=query(cur<<1|1,mid+1,r,ql,qr);
    115     if(ql<=mid && mid<qr)ans-=rc[cur<<1]==lc[cur<<1|1];
    116     return ans;
    117 } 
    118 int ask(int u,int v)
    119 {
    120     int ans=0;
    121     int clt,clp;
    122     int tpu=top[u],tpv=top[v];
    123     while(tpu!=tpv)
    124     {
    125             if(dep[tpu]<dep[tpv])
    126             {
    127                 swap(u,v);swap(tpu,tpv);
    128             }
    129             clt=query_c(1,1,n,pos[tpu]);
    130             clp=query_c(1,1,n,pos[fat[tpu]]);
    131             ans+=query(1,1,n,pos[tpu],pos[u])-(clt==clp);
    132             u=fat[tpu];tpu=top[u];
    133     }
    134     if(dep[u]>dep[v])swap(u,v);
    135     ans+=query(1,1,n,pos[u],pos[v]);
    136     return ans;
    137 }
    138 int main()
    139 {
    140     scanf("%d%d",&n,&m);
    141     for(int i=1;i<=n;++i)scanf("%d",w+i);
    142     for(int u,v,i=1;i<n;++i)
    143     {
    144         scanf("%d%d",&u,&v);
    145         addage(u,v);addage(v,u);
    146     }
    147     dfs(1,0);
    148     getpos(1,1);
    149     memset(delt,-1,sizeof(delt));
    150     build(1,1,n);
    151     char s[3];
    152     int a,b,c;
    153     while(m--)
    154     {
    155         scanf("%s",s);
    156         if(s[0]=='C')
    157         {
    158             scanf("%d%d%d",&a,&b,&c);
    159             change(a,b,c);
    160         }
    161         else
    162         {
    163             scanf("%d%d",&a,&b);
    164             printf("%d
    ",ask(a,b));
    165         }
    166     }
    167     return 0;
    168 }
    View Code
  • 相关阅读:
    78. Subsets
    93. Restore IP Addresses
    71. Simplify Path
    82. Remove Duplicates from Sorted List II
    95. Unique Binary Search Trees II
    96. Unique Binary Search Trees
    312. Burst Balloons
    程序员社交平台
    APP Store开发指南
    iOS框架搭建(MVC,自定义TabBar)--微博搭建为例
  • 原文地址:https://www.cnblogs.com/gryzy/p/10479662.html
Copyright © 2011-2022 走看看