zoukankan      html  css  js  c++  java
  • BZOJ_2243

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

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

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

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

     

    题解:
    链剖裸题+线段树合并,注意合并的时候分清左右区间端点信息

     

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <iostream>
      7 using namespace std;
      8 const int N = 100003;
      9 struct tree1 {
     10     tree1* lson;
     11     tree1* rson;
     12     int sum,l,r,color;
     13     bool pd;
     14     tree1() {
     15         lson = rson = NULL;
     16         sum = l = r = color = 0;
     17         pd = false;
     18     }
     19 }* root,dizhi[N*3];
     20 int n,m,t;
     21 int color[N];
     22 int first[N],to[N*2],next_[N*2],eg;
     23 inline void addedge(int x,int y) {
     24     next_[++eg] = first[x];
     25     first[x] = eg;
     26     to[eg] = y;
     27 }
     28 inline void add(int x,int y) {
     29     addedge(x,y);
     30     addedge(y,x);
     31 }
     32 int fa[N],dep[N],size[N],max_son[N];
     33 inline void dfs1(int u) {
     34     size[u] = 1;
     35     for(int i = first[u] ; i ; i = next_[i]) {
     36         int v = to[i];
     37         if(v==fa[u]) continue;
     38         dep[v] = dep[u] + 1;
     39         fa[v] = u;
     40         dfs1(v);
     41         size[u] += size[v];
     42         max_son[u] = size[max_son[u]] > size[v] ? max_son[u] : v;
     43     }
     44 }
     45 int st[N],tt,top[N],hero[N];
     46 inline void dfs2(int u,int ctop) {
     47     top[u] = ctop;
     48     st[u] = ++tt;
     49     hero[tt] = u;
     50     if(max_son[u]) dfs2(max_son[u],ctop);
     51     for(int i = first[u] ; i ; i = next_[i]) {
     52         int v = to[i];
     53         if(v==fa[u] || v==max_son[u]) continue;
     54         dfs2(v,v);
     55     }
     56 }
     57 inline void build(tree1* tree,int l,int r) {
     58     if(l==r) {
     59         tree->sum = 1;
     60         tree->l = tree->r = color[hero[l]];
     61         return;
     62     }
     63     int mid = (l+r)>>1;
     64     tree->lson = &dizhi[++t];
     65     tree->rson = &dizhi[++t];
     66     build(tree->lson,l,mid);
     67     build(tree->rson,mid+1,r);
     68     tree->sum = tree->lson->sum + tree->rson->sum - (tree->lson->r==tree->rson->l);
     69     tree->l = tree->lson->l;
     70     tree->r = tree->rson->r;
     71 }
     72 inline void push_down(tree1* tree) {
     73     if(tree->pd) {
     74         tree->lson->sum = tree->rson->sum = 1;
     75         tree->lson->pd = tree->rson->pd = true;
     76         tree->lson->l = tree->lson->r = tree->rson->r = tree->rson->l = tree->color;
     77         tree->lson->color = tree->rson->color = tree->color;
     78         tree->pd = false;
     79     }
     80 }
     81 inline void modify2(tree1* tree,int l,int r,int x,int y,int c) {
     82     if(l!=r) push_down(tree);
     83     if(x<=l && r<=y) {
     84         tree->sum = 1;
     85         tree->l = tree->r = c;
     86         tree->pd = true;
     87         tree->color = c;
     88         return;
     89     }
     90     int mid = (l+r)>>1;
     91     if(!(y<l || mid<x)) modify2(tree->lson,l,mid,x,y,c);
     92     if(!(y<mid+1||r<x)) modify2(tree->rson,mid+1,r,x,y,c);
     93     tree->sum = tree->lson->sum + tree->rson->sum - (tree->lson->r==tree->rson->l);
     94     tree->l = tree->lson->l;
     95     tree->r = tree->rson->r;
     96 }
     97 inline void modify(int x,int y,int c) {
     98     while(top[x]!=top[y]) {
     99         if(dep[top[x]]  < dep[top[y]]) swap(x,y);
    100         modify2(root,1,n,st[top[x]],st[x],c);
    101         x = fa[top[x]];
    102     }
    103     if(dep[x] < dep[y]) swap(x,y);
    104     modify2(root,1,n,st[y],st[x],c);
    105 }
    106 struct merge_ {
    107     int sum,l,r;
    108     merge_(int sum_= 0,int l_= 0,int r_= 0) {
    109         sum = sum_;l = l_;r = r_;
    110     }
    111 };
    112 merge_ query2(tree1* tree,int l,int r,int x,int y) {
    113     if(l!=r)push_down(tree);
    114     if(x<=l && r<=y) 
    115         return merge_(tree->sum,tree->l,tree->r);
    116     int mid = (l+r)>>1;
    117     merge_ q1 = merge_(0,-1,-1);
    118     merge_ q2 = merge_(0,-1,-1);
    119     if(!(y<l || mid<x)) q1 = query2(tree->lson,l,mid,x,y);
    120     if(!(y<mid+1||r<x)) q2 = query2(tree->rson,mid+1,r,x,y);
    121     merge_ q3;
    122     q3.sum = q1.sum+q2.sum-(q1.r==q2.l);
    123     q3.l = q1.l!=-1?q1.l:q2.l;
    124     q3.r = q2.r!=-1?q2.r:q1.r;
    125     return q3;
    126 }
    127 inline int query(int x,int y) {
    128     merge_ ans1 = merge_(0,-1,-1);
    129     merge_ ans2 = merge_(0,-1,-1);
    130     while(top[x]!=top[y]) {
    131         if(dep[top[x]] < dep[top[y]]) {
    132             merge_ linshi = query2(root,1,n,st[top[y]],st[y]);
    133             ans2.sum += linshi.sum - (ans2.l==linshi.r);
    134             ans2.l = linshi.l;
    135             y = fa[top[y]];
    136         } else {
    137             merge_ linshi = query2(root,1,n,st[top[x]],st[x]);
    138             ans1.sum += linshi.sum - (ans1.l==linshi.r);
    139             ans1.l = linshi.l;
    140             x = fa[top[x]];
    141         }
    142     }
    143     if(dep[x] < dep[y]) {
    144         merge_ linshi = query2(root,1,n,st[x],st[y]);
    145         return linshi.sum + ans1.sum + ans2.sum - (ans1.l==linshi.l) - (ans2.l==linshi.r);
    146     } else {
    147         merge_ linshi = query2(root,1,n,st[y],st[x]);
    148         return linshi.sum + ans1.sum + ans2.sum - (ans1.l==linshi.r) - (ans2.l==linshi.l);
    149     }
    150 }
    151 int main() {
    152     scanf("%d%d",&n,&m);
    153     for(int i = 1 ; i <= n ; ++i) scanf("%d",&color[i]);
    154     for(int i = 1 ; i < n ; ++i) {
    155         int x,y;
    156         scanf("%d%d",&x,&y);
    157         add(x,y);
    158     }
    159     dfs1(1);
    160     dfs2(1,1);
    161     root = &dizhi[++t];
    162     build(root,1,n);
    163     for(int i = 1 ; i <= m ; ++i) {
    164         char haha;
    165         int x,y,z;
    166         scanf(" %c",&haha);
    167         if(haha=='Q') {
    168             scanf("%d%d",&x,&y);
    169             printf("%d
    ",query(x,y));
    170         } else {
    171             scanf("%d%d%d",&x,&y,&z);
    172             modify(x,y,z);
    173         }
    174     }
    175 }
    View Code

     

     

  • 相关阅读:
    javascript模拟枚举
    javascript实现命名空间效果
    js数组去重
    文件上传插件
    script标签的defer属性
    js数组复制
    更改visual studio2010的主题
    关于json格式在.net前后台传值的详细示例
    where T : class泛型类型约束
    JavaScript模仿鼠标拖动选择功能
  • 原文地址:https://www.cnblogs.com/registerzxr/p/5081716.html
Copyright © 2011-2022 走看看