hdu5029 Relief grain

题目链接

树剖+线段树

将区间修改转化为单点修改,因为如果按DFS序进行修改,那么一定会对DFS序更大的点造成影响

  1 #include<iostream>
  2 #include<vector>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<string>
  6 #include<cstring>
  7 #include<cmath>
  8 #include<algorithm>
  9 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 10 using namespace std;
 11 template <typename Q>
 12 void inin(Q &ret)
 13 {
 14     ret=0;int f=0;char ch=getchar();
 15     while(ch<'0'||ch>'9'){if(ch=='0')f=1;ch=getchar();}
 16     while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
 17     ret=f?-ret:ret;
 18 }
 19 const int xxx=100010;
 20 int head[xxx],Next[xxx<<1],zhi[xxx<<1],n,m,dui[xxx],ans[xxx];
 21 int top[xxx],shen[xxx],fa[xxx],ed,dfn[xxx],son[xxx];
 22 vector<int>in[xxx],out[xxx];
 23 void add(int a,int b)
 24 {
 25     Next[++ed]=head[a],head[a]=ed,zhi[ed]=b;
 26     Next[++ed]=head[b],head[b]=ed,zhi[ed]=a;
 27 }
 28 int dfs(int x)
 29 {
 30     int ret=1,Max=0,temp;
 31     for(int i=head[x];i;i=Next[i])if(zhi[i]!=fa[x])
 32     {
 33         fa[zhi[i]]=x,shen[zhi[i]]=shen[x]+1;
 34         temp=dfs(zhi[i]);
 35         ret+=temp;
 36         if(Max<temp)Max=temp,son[x]=zhi[i];
 37     }
 38     return ret;
 39 }
 40 int tot;
 41 void dfs(int x,int t)
 42 {
 43     if(!x)return ;
 44     top[x]=t;dfn[x]=++tot,dui[tot]=x;
 45     dfs(son[x],t);
 46     for(int i=head[x];i;i=Next[i])if(zhi[i]!=fa[x]&&zhi[i]!=son[x])
 47         dfs(zhi[i],zhi[i]);
 48 }
 49 void change(int x,int y,int z)
 50 {
 51     while(top[x]!=top[y])
 52         if(shen[top[x]]>shen[top[y]])
 53             in[dfn[top[x]]].push_back(z),
 54             out[dfn[x]+1].push_back(z),
 55             x=fa[top[x]];
 56         else in[dfn[top[y]]].push_back(z),
 57             out[dfn[y]+1].push_back(z),
 58             y=fa[top[y]];
 59     if(shen[x]>shen[y])swap(x,y);
 60     in[dfn[x]].push_back(z),out[dfn[y]+1].push_back(z);
 61 }
 62 struct tree
 63 {
 64     int l,r,Max,o;
 65 }t[400040];
 66 void UP(int k)
 67 {
 68     int p1=k<<1,p2=p1|1;
 69     if(t[p1].Max>=t[p2].Max)t[k].Max=t[p1].Max,t[k].o=t[p1].o;
 70     else t[k].Max=t[p2].Max,t[k].o=t[p2].o;
 71 }
 72 void build(int k,int l,int r)
 73 {
 74     t[k].l=l,t[k].r=r;t[k].Max=0,t[k].o=l;
 75     if(l==r)return ;
 76     int mid=(l+r)>>1,p1=k<<1,p2=p1|1;
 77     build(p1,l,mid),build(p2,mid+1,r);
 78     UP(k);
 79 }
 80 void update(int k,int se,int x)
 81 {
 82     if(t[k].l==t[k].r){t[k].Max+=x;return ;}
 83     int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;
 84     if(se<=mid)update(p1,se,x);
 85     else update(p2,se,x);
 86     UP(k);
 87 }
 88 int main()
 89 {
 90     while(scanf("%d%d",&n,&m),n)
 91     {
 92         tot=0;
 93         ed=0;memset(head,0,sizeof head);
 94         memset(son,0,sizeof son);
 95         re(i,2,n)
 96         {
 97             int a,b;inin(a),inin(b);
 98             add(a,b);
 99         }
100         dfs(1);
101         dfs(1,1);int Max=0;
102 //        re(i,1,n)
103 //        {
104 //            printf("%d : ",i);
105 //            cout<<"in:";re(j,0,(int)in[i].size()-1)printf("%d ",in[i][j]);cout<<"
";
106 //            cout<<"out:";re(j,0,(int)out[i].size()-1)printf("%d ",out[i][j]);cout<<"
";
107 //        }
108         re(i,1,m)
109         {
110             int x,y,z;
111             inin(x),inin(y),inin(z);
112             change(x,y,z),Max=max(Max,z);
113         }
114         build(1,1,Max+1);
115         re(i,1,n)
116         {
117             re(j,0,(int)in[i].size()-1)
118                 update(1,in[i][j],1);
119             re(j,0,(int)out[i].size()-1)
120                 update(1,out[i][j],-1);
121             ans[dui[i]]=t[1].Max?t[1].o:0;
122         }
123         re(i,1,n)printf("%d
",ans[i]);
124         re(i,1,n+1)in[i].clear(),out[i].clear();
125     }
126     return 0;
127 } 
原文地址:https://www.cnblogs.com/HugeGun/p/5349980.html