zoukankan      html  css  js  c++  java
  • [USACO11DEC]Grass Planting

    题目大意:
    有一棵结点个数为n的树,有m个操作,可以将一段路径上每条边的权值+1或询问某一个边的权值。

    思路:
    树链剖分+线段树。
    轻重链划分本身比较简单,主要需要思考如何用线段树维护每条链。
    当x,y不在同一条链上时,先处理深度大的链,对于每一个链,建立一棵动态开点的线段树,用一个数组len顺序记录每一条边在链中的编号,然后维护len[x]+1到len[top[x]]这一区间的权值即可。
    处理轻边时,可以直接用一个数组保存它的权值。
    因为轻重边肯定是交替的,因此每次循环都可以先维护一个重边,再维护一个轻边。
    最后x和y肯定会跳到同一条重链上,这时候我们只要维护这条链上从len[x]+1到len[y]的边权即可(实际上就是一个找LCA的过程)。
    询问则比较简单,因为询问的是一条边而非一条路径,因此直接分类讨论这条边是轻边还是重边即可。(网上那么多题解都是没有读题吗?)

    细节:
    轻边不能直接对边上某一点开线段树维护,因为如果这个点刚好是某一个重链的第一个点,就会出现轻重边共用同一棵线段树的情况。
    这题是USACO月赛题,官方题解是用树状数组维护,但是他们是对整棵树开树状数组,所以还是没我跑得快。

      1 #include<cstdio>
      2 #include<cctype>
      3 #include<vector>
      4 inline int getint() {
      5     char ch;
      6     while(!isdigit(ch=getchar()));
      7     int x=ch^'0';
      8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
      9     return x;
     10 }
     11 const int V=100001;
     12 std::vector<int> e[V];
     13 inline void add_edge(const int u,const int v) {
     14     e[u].push_back(v);
     15 }
     16 class SegmentTree {
     17     private:
     18         int val[V<<1],left[V<<1],right[V<<1];
     19         int sz;
     20         int newnode() {
     21             return ++sz;
     22         }
     23     public:
     24         int root[V];
     25         void modify(int &p,const int b,const int e,const int l,const int r) {
     26             if(!p) p=newnode();
     27             if((b==l)&&(e==r)) {
     28                 val[p]++;
     29                 return;
     30             }
     31             int mid=(b+e)>>1;
     32             if(l<=mid) modify(left[p],b,mid,l,std::min(mid,r));
     33             if(r>mid) modify(right[p],mid+1,e,std::max(mid+1,l),r);
     34         }
     35         int query(int &p,const int b,const int e,const int x) {
     36             if(!p) return 0;
     37             if(b==e) return val[p];
     38             int mid=(b+e)>>1;
     39             return (x<=mid?query(left[p],b,mid,x):query(right[p],mid+1,e,x))+val[p];
     40         }
     41 };
     42 SegmentTree t;
     43 int size[V],son[V],top[V],len[V],dep[V],par[V];
     44 void dfs1(const int x,const int p) {
     45     size[x]=1;
     46     dep[x]=dep[p]+1;
     47     par[x]=p;
     48     for(unsigned i=0;i<e[x].size();i++) {
     49         int &y=e[x][i];
     50         if(y==p) continue;
     51         dfs1(y,x);
     52         size[x]+=size[y];
     53         if(size[y]>size[son[x]]) son[x]=y;
     54     }
     55 }
     56 void dfs2(const int x) {
     57     top[x]=(x==son[par[x]])?top[par[x]]:x;
     58     for(unsigned i=0;i<e[x].size();i++) {
     59         int &y=e[x][i];
     60         if(y==par[x]) continue;
     61         dfs2(y);
     62         len[x]=len[son[x]]+1;
     63     }
     64 }
     65 int val[V];
     66 inline void modify(int x,int y) {
     67     while(top[x]!=top[y]) {
     68         if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
     69         if(x!=top[x]) t.modify(t.root[top[x]],1,len[top[x]],len[x]+1,len[top[x]]);
     70         val[top[x]]++;
     71         x=par[top[x]];
     72     }
     73     if(x==y) return;
     74     if(dep[x]<dep[y]) std::swap(x,y);
     75     t.modify(t.root[top[x]],1,len[top[x]],len[x]+1,len[y]);
     76 }
     77 inline int query(int x,int y) {
     78     if(dep[x]<dep[y]) std::swap(x,y);
     79     return top[x]==top[y]?t.query(t.root[top[x]],1,len[top[x]],len[y]):val[x];
     80 }
     81 int main() {
     82     int n=getint(),m=getint();
     83     for(int i=1;i<n;i++) {
     84         int u=getint(),v=getint();
     85         add_edge(u,v);
     86         add_edge(v,u);
     87     }
     88     dfs1(1,0);
     89     dfs2(1);
     90     while(m--) {
     91         char op[2];
     92         scanf("%s",op);
     93         int x=getint(),y=getint();
     94         if(op[0]=='P') {
     95             modify(x,y);
     96         }
     97         else {
     98             printf("%d
    ",query(x,y));
     99         }
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    Codeforces 1316B String Modification
    Codeforces 1305C Kuroni and Impossible Calculation
    Codeforces 1305B Kuroni and Simple Strings
    Codeforces 1321D Navigation System
    Codeforces 1321C Remove Adjacent
    Codeforces 1321B Journey Planning
    Operating systems Chapter 6
    Operating systems Chapter 5
    Abandoned country HDU
    Computer HDU
  • 原文地址:https://www.cnblogs.com/skylee03/p/7484736.html
Copyright © 2011-2022 走看看