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

    2243: [SDOI2011]染色

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 3732  Solved: 1420

    Description

    给定一棵有n个节点的无根树和m个操作,操作有2类:

    1、将节点a到节点b路径上所有点都染成颜色c;

    2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”3段组成:“11”、“222”和“1”

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

    Input

    第一行包含2个整数n和m,分别表示节点数和操作数;

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

    下面 行每行包含两个整数x和y,表示xy之间有一条无向边。

    下面 行每行描述一个操作:

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

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

     

    Output

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

     

    Sample Input

    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

    Sample Output

    3

    1

    2

    HINT

    数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

    Source

    第一轮day1

    解题:树链剖分

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxn = 100010;
      4 struct arc {
      5     int to,next;
      6     arc(int x = 0,int y = -1) {
      7         to = x;
      8         next = y;
      9     }
     10 } e[maxn<<1];
     11 struct node {
     12     int lt,rt,lcolor,rcolor,sum,lazy;
     13 } tree[maxn<<2];
     14 int head[maxn],fa[maxn],top[maxn],dep[maxn];
     15 int son[maxn],siz[maxn],loc[maxn];
     16 int clk,tot;
     17 void add(int u,int v) {
     18     e[tot] = arc(v,head[u]);
     19     head[u] = tot++;
     20 }
     21 void FindHeavyEdge(int u,int father,int depth) {
     22     fa[u] = father;
     23     dep[u] = depth;
     24     son[u] = -1;
     25     siz[u] = 1;
     26     for(int i = head[u]; ~i; i = e[i].next) {
     27         if(e[i].to == father) continue;
     28         FindHeavyEdge(e[i].to,u,depth + 1);
     29         siz[u] += siz[e[i].to];
     30         if(son[u] == -1 || siz[e[i].to] > siz[son[u]])
     31             son[u] = e[i].to;
     32     }
     33 }
     34 void ConnectHeavyEdge(int u,int ancestor) {
     35     top[u] = ancestor;
     36     loc[u] = clk++;
     37     if(son[u] != -1) ConnectHeavyEdge(son[u],ancestor);
     38     for(int i = head[u]; ~i; i = e[i].next) {
     39         if(e[i].to == fa[u] || e[i].to == son[u]) continue;
     40         ConnectHeavyEdge(e[i].to,e[i].to);
     41     }
     42 }
     43 inline void pushdown(int v) {
     44     if(tree[v].lazy != -1) {
     45         tree[v<<1].lazy = tree[v].lazy;
     46         tree[v<<1|1].lazy = tree[v].lazy;
     47         tree[v<<1].lcolor = tree[v<<1].rcolor = tree[v].lazy;
     48         tree[v<<1|1].lcolor = tree[v<<1|1].rcolor = tree[v].lazy;
     49         tree[v].lazy = -1;
     50         tree[v<<1].sum = tree[v<<1|1].sum = 1;
     51     }
     52 }
     53 inline void pushup(int v){
     54     tree[v].sum = tree[v<<1].sum + tree[v<<1|1].sum;
     55     if(tree[v<<1].rcolor == tree[v<<1|1].lcolor) tree[v].sum--;
     56     tree[v].lcolor = tree[v<<1].lcolor;
     57     tree[v].rcolor = tree[v<<1|1].rcolor;
     58 }
     59 void build(int lt,int rt,int v) {
     60     tree[v].lt = lt;
     61     tree[v].rt = rt;
     62     tree[v].lazy = -1;
     63     if(lt == rt) {
     64         tree[v].lcolor = tree[v].rcolor = -1;
     65         tree[v].sum = 1;
     66         return;
     67     }
     68     int mid = (lt + rt)>>1;
     69     build(lt,mid,v<<1);
     70     build(mid + 1,rt,v<<1|1);
     71     pushup(v);
     72 }
     73 void update(int lt,int rt,int color,int v) {
     74     if(lt <= tree[v].lt && rt >= tree[v].rt) {
     75         tree[v].lcolor = tree[v].rcolor = color;
     76         tree[v].lazy = color;
     77         tree[v].sum = 1;
     78         return;
     79     }
     80     pushdown(v);
     81     if(lt <= tree[v<<1].rt) update(lt,rt,color,v<<1);
     82     if(rt >= tree[v<<1|1].lt) update(lt,rt,color,v<<1|1);
     83     pushup(v);
     84 }
     85 int query(int lt,int rt,int v) {
     86     if(lt == tree[v].lt && rt == tree[v].rt) return tree[v].sum;
     87     pushdown(v);
     88     if(rt <= tree[v<<1].rt) return query(lt,rt,v<<1);
     89     if(lt >= tree[v<<1|1].lt) return query(lt,rt,v<<1|1);
     90     int tmp = query(lt,tree[v<<1].rt,v<<1) + query(tree[v<<1|1].lt,rt,v<<1|1);
     91     if(tree[v<<1].rcolor == tree[v<<1|1].lcolor) tmp--;
     92     pushup(v);
     93     return tmp;
     94 }
     95 void CHANGE(int u,int v,int color) {
     96     while(top[u] != top[v]) {
     97         if(dep[top[u]] < dep[top[v]]) swap(u,v);
     98         update(loc[top[u]],loc[u],color,1);
     99         u = fa[top[u]];
    100     }
    101     if(dep[u] > dep[v]) swap(u,v);
    102     update(loc[u],loc[v],color,1);
    103 }
    104 int getColor(int pos,int v){
    105     if(tree[v].lt == tree[v].rt) return tree[v].lcolor;
    106     pushdown(v);
    107     if(pos <= tree[v<<1].rt) return getColor(pos,v<<1);
    108     if(pos >= tree[v<<1|1].lt) return getColor(pos,v<<1|1);
    109     pushup(v);
    110 }
    111 int QUERY(int u,int v) {
    112     int ret = 0;
    113     while(top[u] != top[v]) {
    114         if(dep[top[u]] < dep[top[v]]) swap(u,v);
    115         ret += query(loc[top[u]],loc[u],1);
    116         if(getColor(loc[top[u]],1) == getColor(loc[fa[top[u]]],1)) --ret;
    117         u = fa[top[u]];
    118     }
    119     if(dep[u] > dep[v]) swap(u,v);
    120     ret += query(loc[u],loc[v],1);
    121     return ret;
    122 }
    123 int val[maxn],n,m;
    124 int main() {
    125     int u,v,color;
    126     while(~scanf("%d%d",&n,&m)) {
    127         memset(head,-1,sizeof head);
    128         tot = clk = 0;
    129         for(int i = 1; i <= n; ++i) scanf("%d",val + i);
    130         for(int i = 1; i < n; ++i) {
    131             scanf("%d%d",&u,&v);
    132             add(u,v);
    133             add(v,u);
    134         }
    135         FindHeavyEdge(1,0,0);
    136         ConnectHeavyEdge(1,1);
    137         build(0,clk-1,1);
    138         for(int i = 1; i <= n; ++i)
    139             update(loc[i],loc[i],val[i],1);
    140         char op[10];
    141         while(m--) {
    142             scanf("%s",op);
    143             if(op[0] == 'Q') {
    144                 scanf("%d%d",&u,&v);
    145                 printf("%d
    ",QUERY(u,v));
    146             } else if(op[0] == 'C') {
    147                 scanf("%d%d%d",&u,&v,&color);
    148                 CHANGE(u,v,color);
    149             }
    150         }
    151     }
    152     return 0;
    153 }
    154 /*
    155 6 5
    156 2 2 1 2 1 1
    157 1 2
    158 1 3
    159 2 4
    160 2 5
    161 2 6
    162 Q 3 5
    163 C 2 1 1
    164 Q 3 5
    165 C 5 1 2
    166 Q 3 5
    167 */
    View Code
  • 相关阅读:
    vue实战使用ajax请求后台数据(小白)
    jQuery实现tab栏切换效果
    jQuery下的ajax实例
    数据库之视图更新
    SQL Server 全文索引创建
    SQL Server 分区表
    数据快照 (Database Snapshot)
    FileStream
    ODBC,OLEDB,ADO,ADO.net,JDBC 理解
    拖延症?贪玩?来试试"百万金币时间管理法"
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4845439.html
Copyright © 2011-2022 走看看