[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 }
树链剖分模板题。