[USACO2015DEC]Max Flow

题目大意:
  给你一棵n个点的树,有m次操作,每次将给定的路径上所有点的点权+1。
  问最后最大的点权是多少。

思路:
  

  1 #include<cstdio>
  2 #include<cctype>
  3 #include<vector>
  4 inline int getint() {
  5     register char ch;
  6     while(!isdigit(ch=getchar()));
  7     register int x=ch^'0';
  8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
  9     return x;
 10 }
 11 const int N=100001;
 12 std::vector<int> e[N];
 13 inline void add_edge(const int &u,const int &v) {
 14     e[u].push_back(v);
 15     e[v].push_back(u);
 16 }
 17 class SegmentTree {
 18     #define _left <<1
 19     #define _right <<1|1
 20     private:
 21         int max[N<<2],tag[N<<2];
 22         void push_down(const int &p) {
 23             max[p _left]+=tag[p];
 24             max[p _right]+=tag[p];
 25             tag[p _left]+=tag[p];
 26             tag[p _right]+=tag[p];
 27             tag[p]=0;
 28         }
 29         void push_up(const int &p) {
 30             max[p]=std::max(max[p _left],max[p _right]);
 31         }
 32     public:
 33         void modify(const int &p,const int &b,const int &e,const int &l,const int &r) {
 34             if(b==l&&e==r) {
 35                 max[p]++;
 36                 tag[p]++;
 37                 return;
 38             }
 39             push_down(p);
 40             const int mid=(b+e)>>1;
 41             if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r));
 42             if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r);
 43             push_up(p);
 44         }
 45         int query() const {
 46             return max[1];
 47         }
 48     #undef _left
 49     #undef _right
 50 };
 51 SegmentTree t;
 52 int n,par[N],dep[N],top[N],low[N],size[N],son[N],id[N];
 53 void dfs1(const int &x,const int &par) {
 54     ::par[x]=par;
 55     dep[x]=dep[par]+1;
 56     size[x]=1;
 57     for(unsigned i=0;i<e[x].size();i++) {
 58         const int &y=e[x][i];
 59         if(y==par) continue;
 60         dfs1(y,x);
 61         size[x]+=size[y];
 62         if(size[y]>size[son[x]]) son[x]=y;
 63     }
 64 }
 65 void dfs2(const int &x) {
 66     id[x]=++id[0];
 67     if(x==son[par[x]]) {
 68         top[x]=top[par[x]];
 69     } else {
 70         top[x]=x;
 71     }
 72     if(son[x]) dfs2(son[x]);
 73     for(unsigned i=0;i<e[x].size();i++) {
 74         const int &y=e[x][i];
 75         if(y==par[x]||y==son[x]) continue;
 76         dfs2(y);
 77     }
 78 }
 79 inline void modify(int u,int v) {
 80     while(top[u]!=top[v]) {
 81         if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
 82         t.modify(1,1,n,id[top[u]],id[u]);
 83         u=par[top[u]];
 84     }
 85     if(dep[u]<dep[v]) std::swap(u,v);
 86     t.modify(1,1,n,id[v],id[u]);
 87 }
 88 int main() {
 89     n=getint();
 90     const int m=getint();
 91     for(register int i=1;i<n;i++) {
 92         add_edge(getint(),getint());
 93     }
 94     dfs1(1,0);
 95     dfs2(1);
 96     for(register int i=0;i<m;i++) {
 97         const int s=getint(),t=getint();
 98         modify(s,t);
 99     }
100     printf("%d\n",t.query());
101     return 0;
102 }

 

树链剖分模板题。

posted @ 2017-12-19 15:14  skylee03  阅读(174)  评论(0编辑  收藏  举报