zoukankan      html  css  js  c++  java
  • 「luogu2486」[SDOI2011] 染色

    https://www.luogu.org/problemnew/show/P2486

    轻重链剖分后,问题转化为一个链上的问题;

    线段树维护区间内的颜色段数量,左端点、右端点的颜色;

    线段树注意事项 {

      合并时判断两个区间的相邻端点是否相同;

      查询时同上,但要注意是否两段是不是都在查询区间内;

      lazy_tag和更新颜色,嘻嘻嘻。

    }

    p.s 树上查询颜色段要判断两条链的端点是否颜色相同;

    特别地,对于在同一条链上的两个节点之间的查询,要判断两个点和与它相邻点的颜色是否相同。

    代码如下 :

      1 // 15owzLy1
      2 //luogu2486.cpp
      3 //2018 09 26      18:38:11
      4 #include <iostream>
      5 #include <cstdio>
      6 #include <cstring>
      7 #include <algorithm>
      8 #define lson tl, mid, rt<<1
      9 #define rson mid+1, tr, rt<<1|1
     10 typedef long long ll;
     11 typedef double db;
     12 using namespace std;
     13 
     14 const int N = 100005;
     15 struct node { int l, r, cnt; };
     16 struct info {
     17     int next, to;
     18 }edge[N<<1];
     19 int head[N], dfn[N], size[N], hson[N], fa[N], dep[N], q, n;
     20 int front[N], cl[N];
     21 
     22 template<typename T>inline void read(T &x_) {
     23     x_=0;bool f_=0;char c_=getchar();
     24     while(c_<'0'||c_>'9'){f_|=(c_=='-');c_=getchar();}
     25     while(c_>='0'&&c_<='9'){x_=(x_<<1)+(x_<<3)+(c_^48);c_=getchar();}
     26     x_=f_?-x_:x_;
     27 }
     28 
     29 struct Segment_Tree {
     30     node t[N<<2]; int lazy[N<<2];
     31     inline void push_up(int rt) {
     32         t[rt].cnt=t[rt<<1].cnt+t[rt<<1|1].cnt;
     33         if(t[rt<<1].r==t[rt<<1|1].l) t[rt].cnt--;
     34         t[rt].l=t[rt<<1].l, t[rt].r=t[rt<<1|1].r;
     35     }
     36     inline void spread(int rt) {
     37         t[rt<<1].cnt=1; t[rt<<1|1].cnt=1;
     38         t[rt<<1].l=t[rt<<1|1].r=t[rt<<1].r=t[rt<<1|1].l=
     39         lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
     40         lazy[rt]=0;
     41     }
     42     void update(int del, int l, int r, int tl, int tr, int rt) {
     43         if(l<=tl&&tr<=r) {
     44             t[rt].cnt=1; t[rt].l=t[rt].r=lazy[rt]=del;
     45             return ;
     46         }
     47         if(lazy[rt]) spread(rt);
     48         int mid=(tl+tr)>>1;
     49         if(mid>=l) update(del, l, r, lson);
     50         if(mid<r)  update(del, l, r, rson);
     51         push_up(rt);
     52     }
     53     int query(int l, int r, int tl, int tr, int rt) {
     54         if(l<=tl&&tr<=r) return t[rt].cnt;
     55         if(lazy[rt]) spread(rt);
     56         int mid=(tl+tr)>>1, res=0, k=0;
     57         if(mid>=l) res+=query(l, r, lson), ++k;
     58         if(mid<r)  res+=query(l, r, rson), ++k;
     59         if(t[rt<<1].r==t[rt<<1|1].l&&k>=2) res--;
     60         return res;
     61     }
     62     int ask_cl(int pos, int tl, int tr, int rt) {
     63         if(tl==tr) return t[rt].l;
     64         if(lazy[rt]) spread(rt);
     65         int mid=(tl+tr)>>1;
     66         if(mid>=pos)  return ask_cl(pos, lson);
     67         else          return ask_cl(pos, rson);
     68     }
     69 }T;
     70 
     71 inline void jb(int u, int v) {
     72     edge[++edge[0].to].to=v;
     73     edge[edge[0].to].next=head[u];
     74     head[u]=edge[0].to;
     75 }
     76 
     77 void dfs(int u) {
     78     size[u]=1;
     79     for(int i=head[u];i;i=edge[i].next) {
     80         int v=edge[i].to;
     81         if(v==fa[u]) continue;
     82         fa[v]=u; dep[v]=dep[u]+1;
     83         dfs(v);
     84         size[u]+=size[v];
     85         if(size[hson[u]]<size[v]) hson[u]=v;
     86     }
     87 }
     88 
     89 inline void dfs_(int u, int father) {
     90     dfn[u]=++dfn[0]; front[u]=father;
     91     if(hson[u]) dfs_(hson[u], father);
     92     for(int i=head[u];i;i=edge[i].next) {
     93         int v=edge[i].to;
     94         if(v==fa[u]||v==hson[u]) continue;
     95         dfs_(v, v);
     96     }
     97 }
     98 
     99 inline void update(int u, int v, int del) {
    100     while(front[u]!=front[v]) {
    101         if(dep[front[u]]>dep[front[v]]) swap(u, v);
    102         T.update(del, dfn[front[v]], dfn[v], 1, n, 1);
    103         v=fa[front[v]];
    104     }
    105     if(dep[u]>dep[v]) swap(u, v);
    106     T.update(del, dfn[u], dfn[v], 1, n, 1);
    107 }
    108 
    109 inline int query(int u, int v) {
    110     int res=0, clu=-1, clv=-1, tmp, k=0;
    111     while(front[u]!=front[v]) {
    112         if(dep[front[u]]>dep[front[v]])
    113             swap(u, v), swap(clu, clv);
    114         res+=T.query(dfn[front[v]], dfn[v], 1, n, 1);
    115         tmp=T.ask_cl(dfn[v], 1, n, 1);
    116         if(clv==tmp) --res;
    117         clv=T.ask_cl(dfn[front[v]], 1, n, 1);
    118         v=fa[front[v]];
    119     }
    120     if(dep[u]>dep[v])
    121         swap(u, v), swap(clu, clv);
    122     if(clu==T.ask_cl(dfn[u], 1, n, 1)) res--, ++k;
    123     if(clv==T.ask_cl(dfn[v], 1, n, 1)) res--, ++k;
    124     res+=T.query(dfn[u], dfn[v], 1, n, 1);
    125     return res;
    126 }
    127 
    128 int main() {
    129 #ifndef ONLINE_JUDGE
    130     freopen("luogu2486.in","r",stdin);
    131     freopen("luogu2486.out","w",stdout);
    132 #endif
    133     int x, y, z; char opt[5];
    134     read(n), read(q);
    135     for(int i=1;i<=n;i++) read(cl[i]);
    136     for(int i=1;i<n;i++) read(x), read(y), jb(x, y), jb(y, x);
    137     dep[1]=1;
    138     dfs(1); dfs_(1,1);
    139     for(int i=1;i<=n;i++) T.update(cl[i], dfn[i], dfn[i], 1, n, 1);
    140     while(q--) {
    141         scanf("%s", opt); read(x), read(y);
    142         if(opt[0]=='Q') printf("%d
    ", query(x, y));
    143         else            read(z),    update(x, y, z);
    144     }
    145     return 0;
    146 }
    View Code
  • 相关阅读:
    OC的内存管理(二)ARC
    OC中@class的使用
    OC的内存管理(一)
    OC中自定义构造方法
    【数据结构作业—01】用单循环链表解决约瑟夫问题
    TJU Problem 1090 City hall
    GPA
    HDOJ 1061 Rightmost Digit
    TJU Problem 2857 Digit Sorting
    TJU Problem 1015 Gridland
  • 原文地址:https://www.cnblogs.com/15owzLy1-yiylcy/p/9726369.html
Copyright © 2011-2022 走看看