zoukankan      html  css  js  c++  java
  • bzoj 2243(大学ACM恢复训练)

    2243: [SDOI2011]染色

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 10083  Solved: 3843
    [Submit][Status][Discuss]

    Description

    给定一棵有n个节点的无根树和m个操作,操作有2类:
    1、将节点a到节点b路径上所有点都染成颜色c;
    2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),
    如“112221”由3段组成:“11”、“222”和“1”。
    请你写一个程序依次完成这m个操作。

    裸的链剖,写加调55分钟,代码能力太差。不要有畏惧心理,多写来提高。

    注意把函数模块化,更新统一写

    注意区间合并的先后顺序,深度小的在上,相当于左区间。链顶合并相当于左左合并,要特判。

    维护左右端点颜色即可

    链剖中链查询可以对每条链建线段树,应该快些,但因为线段树太丑反而更慢。

    所以留坑,优化线段树。。。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 #define maxn 100020
      7 
      8 struct node{
      9     int next,to;
     10 }e[maxn * 2];
     11 struct data{
     12     int lc,rc,num;
     13     data(){ lc = rc = num = 0; }
     14     data(int a,int b,int c):lc(a),rc(b),num(c){};
     15 };
     16 struct node2{
     17     int ls,rs,tag;
     18     data dt;
     19 }sgt[maxn * 20];
     20 int head[maxn],cnt;
     21 int n,m,col[maxn],tot,root[maxn];
     22 int sz[maxn],son[maxn],fa[maxn],id[maxn],top[maxn],dth[maxn],len[maxn];
     23 
     24 inline void adde(int x,int y){
     25     e[++cnt].to = y;
     26     e[cnt].next = head[x];
     27     head[x] = cnt;
     28 }
     29 void dfs(int x){
     30     sz[x] = 1;
     31     for (int i = head[x] ; i ; i = e[i].next){
     32         if ( e[i].to == fa[x] ) continue;
     33         fa[e[i].to] = x , dth[e[i].to] = dth[x] + 1;
     34         dfs(e[i].to);
     35         sz[x] += sz[e[i].to];
     36         if ( sz[son[x]] < sz[e[i].to] ) son[x] = e[i].to; 
     37     }
     38 }
     39 void dfs2(int x){
     40     if ( son[x] ){
     41         top[son[x]] = top[x] , id[son[x]] = ++len[top[x]];
     42         dfs2(son[x]);
     43     }
     44     for (int i = head[x] ; i ; i = e[i].next){
     45         if ( e[i].to == fa[x] || e[i].to == son[x] ) continue;
     46         top[e[i].to] = e[i].to , id[e[i].to] = len[e[i].to] = 1;
     47         dfs2(e[i].to);
     48     }
     49 }
     50 inline data update(data dt1,data dt2){
     51     data cur;
     52     cur.num = dt1.num + dt2.num - (dt1.rc == dt2.lc);
     53     if ( dt1.num && dt2.num ) cur.lc = dt1.lc , cur.rc = dt2.rc;
     54     else if ( dt1.num ) cur.lc = dt1.lc , cur.rc = dt1.rc;
     55     else if ( dt2.num ) cur.lc = dt2.lc , cur.rc = dt2.rc;
     56     return cur;
     57 }
     58 inline void cov(int x,int c){
     59     if ( !x ) return;
     60     sgt[x].dt = data(c,c,1);
     61     sgt[x].tag = c;
     62 }
     63 inline void pushdown(int x){
     64     if ( sgt[x].tag != -1 ){
     65         int ls = sgt[x].ls , rs = sgt[x].rs;
     66         cov(ls,sgt[x].tag) , cov(rs,sgt[x].tag);
     67         sgt[x].tag = -1;
     68     }
     69 }
     70 /*inline void update(int x){
     71     int ls = sgt[x].ls , rs = sgt[x].rs;
     72     sgt[x].num = sgt[ls].num + sgt[rs].num - (sgt[ls].rc == sgt[rs].lc);
     73     if ( ls && rs ) sgt[x].lc = sgt[ls].lc , sgt[x].rc = sgt[rs].rc;
     74     else if ( ls ) sgt[x].lc = sgt[ls].lc , sgt[x].rc = sgt[ls].rc;
     75     else sgt[x].lc = sgt[rs].lc , sgt[x].rc = sgt[rs].rc;
     76 }*/
     77 void insert(int &x,int l,int r,int id,int c){
     78     if ( !x ) x = ++tot , sgt[x].tag = -1;
     79     if ( l == r ){    sgt[x].dt = data(c,c,1); return; }
     80     int mid = (l + r) >> 1;
     81     if ( id <= mid ) insert(sgt[x].ls,l,mid,id,c);
     82     else insert(sgt[x].rs,mid + 1,r,id,c);
     83     sgt[x].dt = update(sgt[sgt[x].ls].dt,sgt[sgt[x].rs].dt);
     84 }
     85 void build(){
     86     for (int i = 1 ; i <= n ; i++)
     87         insert(root[top[i]],1,len[top[i]],id[i],col[i]);
     88 }
     89 void modify(int x,int l,int r,int ls,int rs,int c){
     90     if ( !x ) return;
     91     if ( ls <= l && rs >= r ){ cov(x,c); return; }
     92     pushdown(x);
     93     int mid = (l + r) >> 1;
     94     if ( ls <= mid ) modify(sgt[x].ls,l,mid,ls,rs,c);
     95     if ( rs > mid ) modify(sgt[x].rs,mid + 1,r,ls,rs,c);
     96     sgt[x].dt = update(sgt[sgt[x].ls].dt,sgt[sgt[x].rs].dt);
     97 }
     98 data query(int x,int l,int r,int ls,int rs){
     99     if ( !x ) return data(0,0,0);
    100     pushdown(x);
    101     if ( ls <= l && rs >= r ) return sgt[x].dt;
    102     int mid = (l + r) >> 1; data dt1,dt2;
    103     if ( ls <= mid ) dt1 = query(sgt[x].ls,l,mid,ls,rs);
    104     if ( rs > mid ) dt2 = query(sgt[x].rs,mid + 1,r,ls,rs);
    105     return update(dt1,dt2);
    106 }
    107 int query(int x,int y){
    108     data dt1,dt2,dt3;
    109     while ( top[x] != top[y] ){
    110         if ( dth[top[x]] > dth[top[y]] ){
    111             dt1 = update(query(root[top[x]],1,len[top[x]],1,id[x]),dt1); //左边深度更小,注意合并顺序
    112             x = fa[top[x]];
    113         }
    114         else{
    115             dt2 = update(query(root[top[y]],1,len[top[y]],1,id[y]),dt2);
    116             y = fa[top[y]];
    117         }
    118     }
    119     //链顶合并有特殊情况
    120     if ( dth[x] < dth[y] )
    121         dt2 = update(query(root[top[x]],1,len[top[x]],id[x],id[y]),dt2);
    122     else
    123         dt1 = update(query(root[top[x]],1,len[top[x]],id[y],id[x]),dt1);
    124     swap(dt1.lc,dt1.rc);
    125     return update(dt1,dt2).num;
    126 }
    127 void modify(int x,int y,int c){
    128     while ( top[x] != top[y] ){
    129         if ( dth[top[x]] < dth[top[y]] ) swap(x,y);
    130         modify(root[top[x]],1,len[top[x]],1,id[x],c);
    131         x = fa[top[x]];
    132     }
    133     if ( dth[x] < dth[y] ) modify(root[top[x]],1,len[top[x]],id[x],id[y],c);
    134     else modify(root[top[x]],1,len[top[x]],id[y],id[x],c);
    135 }
    136 int main(){
    137     freopen("input.txt","r",stdin);
    138     scanf("%d %d",&n,&m);
    139     for (int i = 1 ; i <= n ; i++) scanf("%d",&col[i]);
    140     for (int i = 1 ; i < n ; i++){
    141         int x,y;
    142         scanf("%d %d",&x,&y);
    143         adde(x,y) , adde(y,x);
    144     }
    145     dfs(1) , id[1] = len[1] = top[1] = 1 , dfs2(1) , build();
    146     while ( m-- ){
    147         char ch[10]; int a,b,c;
    148         scanf("%s",ch);
    149         if ( ch[0] == 'Q' ){
    150             scanf("%d %d",&a,&b);
    151             printf("%d
    ",query(a,b));
    152         }
    153         else{
    154             scanf("%d %d %d",&a,&b,&c);
    155             modify(a,b,c);
    156         }
    157     }
    158     return 0;
    159 }
    View Code
  • 相关阅读:
    GridControl主从表设置
    Asp.net Ajax框架教程
    实现类似百度下拉框自动匹配功能
    将一个DataTable分解成多个DataTable
    找不到可安装的ISAM ,asp.net读取数据丢失,解决的一列里有字符与数字的
    StringCollection FAQ [C#, BCL]
    从枚举的初始化说起 [C#]
    当多态遇上数组 ... [C++] (Rewritten)
    我并不是不闻不问![C#]
    当多态遇上数组 ... [C++, C++/CLI, C#]
  • 原文地址:https://www.cnblogs.com/zqq123/p/9242792.html
Copyright © 2011-2022 走看看