zoukankan      html  css  js  c++  java
  • bzoj2243: [SDOI2011]染色--线段树+树链剖分

    此题代码量较大。。但是打起来很爽

    原本不用lca做一直wa不知道为什么。。

    后来改lca重打了一遍= =结果一遍就AC了orz

    题目比较裸,也挺容易打,主要是因为思路可以比较清晰

    另:加读入优化比没加快了1.3s。。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<algorithm>
      4 using namespace std;
      5 const int maxn = 100010;
      6 struct node{
      7     int l,r,lc,rc,sum,lz;
      8 }t[maxn*4];
      9 struct edge{
     10     int to,next;
     11 }e[maxn*2];
     12 int n,m,u,v,tot,cnt,logn=0;
     13 int head[maxn],son[maxn],pre[maxn],tree[maxn],top[maxn],dep[maxn],fa[maxn][30],size[maxn],col[maxn];
     14 
     15 inline void read(int &x){
     16     char cc=getchar(); x=0; int f=1;
     17     while (cc<'0' || cc>'9'){if (cc=='-') f=-1; cc=getchar();}
     18     while (cc>='0' && cc<='9') x=x*10+cc-'0',cc=getchar(); x*=f;
     19 }
     20 
     21 inline void insert(int u, int v){
     22     e[++tot].to=v; e[tot].next=head[u]; head[u]=tot;
     23 }
     24 
     25 inline void dfs1(int u, int f, int d){
     26     size[u]=1; fa[u][0]=f; dep[u]=d;
     27     for (int i=1; i<=logn; i++) fa[u][i]=fa[fa[u][i-1]][i-1];
     28     for (int i=head[u]; i!=-1; i=e[i].next){
     29         int v=e[i].to;
     30         if (v==f) continue;
     31         dfs1(v,u,d+1);
     32         size[u]+=size[v];
     33         if (!son[u] || size[v]>size[son[u]]) son[u]=v;
     34     }
     35 }
     36 
     37 inline void dfs2(int u, int num){
     38     top[u]=num; tree[u]=++cnt;
     39     pre[cnt]=u;
     40     if (!son[u]) return;
     41     dfs2(son[u],num);
     42     for (int i=head[u]; i!=-1; i=e[i].next)
     43         if (e[i].to!=fa[u][0] && e[i].to!=son[u])
     44             dfs2(e[i].to,e[i].to);
     45 }
     46 
     47 inline int lca(int u, int v){
     48     if (dep[u]>dep[v]) swap(u,v);
     49     while (dep[u]<dep[v]){
     50         for (int i=logn; i>=0; i--)
     51             if (dep[u]<dep[fa[v][i]])
     52                 v=fa[v][i];
     53         v=fa[v][0];
     54     }
     55     if (u==v) return u;
     56     for (int i=logn; i>=0; i--)
     57         if (fa[u][i]!=fa[v][i]){
     58             u=fa[u][i];
     59             v=fa[v][i];
     60         }
     61     u=fa[u][0];
     62     return u;
     63 }
     64 
     65 inline void pushdown(int x){
     66     if (t[x].lz){
     67         t[x<<1].lz=t[x<<1|1].lz=t[x].lz;
     68         t[x<<1].lc=t[x<<1].rc=t[x<<1|1].lc=t[x<<1|1].rc=t[x].lz;
     69         t[x<<1].sum=t[x<<1|1].sum=1;
     70         t[x].lz=0;
     71     }
     72 }
     73 
     74 inline void pushup(int x){
     75     t[x].lc=t[x<<1].lc; t[x].rc=t[x<<1|1].rc;
     76     t[x].sum=t[x<<1].sum+t[x<<1|1].sum-(t[x<<1].rc==t[x<<1|1].lc);
     77 }
     78 
     79 inline int query(int a, int b, int x){
     80     int l=t[x].l, r=t[x].r;
     81     if (a==l && r==b) return t[x].sum;
     82     int mid=l+r>>1;
     83     pushdown(x);
     84     if (b<=mid) return query(a,b,x<<1);
     85     else if (a>mid) return query(a,b,x<<1|1);
     86     else return query(a,mid,x<<1)+query(mid+1,b,x<<1|1)-(t[x<<1].rc==t[x<<1|1].lc);
     87 }
     88 
     89 inline void update(int a, int b, int c, int x){
     90     int l=t[x].l, r=t[x].r;
     91     if (a==l && r==b){
     92         t[x].lc=t[x].rc=t[x].lz=c;
     93         t[x].sum=1;
     94         return;
     95     }
     96     int mid=l+r>>1;
     97     pushdown(x);
     98     if (b<=mid) update(a,b,c,x<<1);
     99     else if (a>mid) update(a,b,c,x<<1|1);
    100     else{
    101         update(a,mid,c,x<<1);
    102         update(mid+1,b,c,x<<1|1);
    103     }
    104     pushup(x);
    105 }
    106 
    107 inline int get_col(int a, int x){
    108     int l=t[x].l, r=t[x].r;
    109     if (l==r) return t[x].lc;
    110     pushdown(x);
    111     int mid=l+r>>1;
    112     if (a<=mid) return get_col(a,x<<1);
    113     else return get_col(a,x<<1|1);
    114 }
    115 
    116 inline void build(int l, int r, int x){
    117     t[x].l=l; t[x].r=r;
    118     if (l==r){
    119         t[x].lc=t[x].rc=col[pre[l]];
    120         t[x].sum=1;
    121         return;
    122     }
    123     int mid=l+r>>1;
    124     if (l<=mid) build(l,mid,x<<1);
    125     if (r>mid) build(mid+1,r,x<<1|1);
    126     pushup(x);
    127 }
    128 
    129 inline void change(int x, int f, int c){
    130     while (top[x]!=top[f]){
    131         update(tree[top[x]],tree[x],c,1);
    132         x=fa[top[x]][0];
    133     }
    134     update(tree[f],tree[x],c,1);
    135 }
    136 
    137 inline int get_sum(int x, int f){
    138     int res=0;
    139     while (top[x]!=top[f]){
    140         res+=query(tree[top[x]],tree[x],1);
    141         if (get_col(tree[top[x]],1)==get_col(tree[fa[top[x]][0]],1)) res--;
    142         x=fa[top[x]][0];
    143     }
    144     res+=query(tree[f],tree[x],1);
    145     return res;
    146 }
    147 
    148 int main(){
    149     read(n); read(m);
    150     while ((1<<logn)<n) logn++;
    151     for (int i=1; i<=n; i++) read(col[i]),col[i]++;
    152     tot=-1; memset(head,-1,sizeof(head));
    153     for (int i=1; i<n; i++){
    154         read(u); read(v);
    155         insert(u,v); insert(v,u);
    156     }
    157     cnt=0;
    158     dfs1(1,0,1); dfs2(1,0);
    159     build(1,n,1);
    160     char s[5];
    161     while (m--){
    162         scanf("%s", s);
    163         if (s[0]=='Q'){
    164             read(u); read(v);
    165             int t=lca(u,v);
    166             printf("%d
    ", get_sum(u,t)+get_sum(v,t)-1);
    167         }
    168         else{
    169             int color;
    170             read(u); read(v); read(color);
    171             int t=lca(u,v);
    172             color++;
    173             change(u,t,color);
    174             change(v,t,color);
    175         }
    176     }
    177     return 0;
    178 }
  • 相关阅读:
    poj 3041 Asteroids (最大匹配最小顶点覆盖——匈牙利模板题)
    poj 2060 Taxi Cab Scheme (最小路径覆盖)
    poj 2728 Desert King (最小比例生成树)
    poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)
    poj 3463 Sightseeing( 最短路与次短路)
    研究生flag
    插入排序和堆排序
    根据二叉树的中序遍历和层次遍历还原二叉树
    关于AVL实现的代码记录
    回文数猜想(与6174问题很像)
  • 原文地址:https://www.cnblogs.com/mzl0707/p/5537093.html
Copyright © 2011-2022 走看看