码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3083 遥远的国度

时间:2016-04-23 18:02:42      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:

  树链剖分,先求出每个点的dfs序区间,查询时假设当前根为x,查询点为y,他们的dfs序分别为[xl,xr],[yl,yr],有三种情况,第一种x=y那么直接输出[1,n]的最小值,第二种这两个区间分离或者[xl,xr]包含[yl,yr],那么直接查询[yl,yr]的最小值,第三种[yl,yr]包含[xl,xr],找到x到y的路径上离y最近的点z,其区间为[zl,zr],那么需要输出min([1,zl-1],[zr+1,n])。

  代码

  1 #include<cstdio>
  2 #include<algorithm>
  3 #define N 2000010
  4 using namespace std;
  5 typedef long long ll;
  6 int dp,pre[N],p[N],tt[N],f[N],gf[N],go[N];
  7 int L[N],R[N],tot,n,m,i,deep[N];
  8 int l[N],r[N],a,b,root,typ;
  9 int jump[110000][19];
 10 ll value[N],e[N],c,v[N],s[N],inf;
 11 void link(int x,int y)
 12 {
 13     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
 14 }
 15 void dfs1(int x,int fa)
 16 {
 17     int i;
 18     s[x]=1;f[x]=fa;deep[x]=deep[fa]+1;
 19     jump[x][0]=fa;for (i=1;i<=17;i++) jump[x][i]=jump[jump[x][i-1]][i-1];
 20     i=p[x];
 21     while (i)
 22     {
 23         if (tt[i]!=fa)
 24         {
 25             dfs1(tt[i],x);
 26             s[x]+=s[tt[i]];
 27             if (s[tt[i]]>s[go[x]]) go[x]=tt[i];
 28         }
 29         i=pre[i];
 30     }
 31 }
 32 void dfs2(int x,int Fa,int fa)
 33 {
 34     int i=p[x];
 35     L[x]=++tot;gf[x]=Fa;e[tot]=value[x];
 36     if (go[x]) dfs2(go[x],Fa,x);
 37     while (i)
 38     {
 39         if ((tt[i]!=fa)&&(tt[i]!=go[x]))
 40             dfs2(tt[i],tt[i],x);
 41         i=pre[i];
 42     }
 43     R[x]=tot;
 44 }
 45 void build(int x,int a,int b)
 46 {
 47     l[x]=a;r[x]=b;
 48     if (b-a>1)
 49     {
 50         int m=(l[x]+r[x])>>1;
 51         build(2*x,a,m);
 52         build(2*x+1,m,b);
 53         s[x]=min(s[2*x],s[2*x+1]);
 54     }
 55     else
 56         s[x]=e[b];
 57 }
 58 void clean(int x)
 59 {
 60     if (v[x])
 61     {
 62         s[x]=v[x];
 63         v[2*x]=v[x];
 64         v[2*x+1]=v[x];
 65         v[x]=0;
 66     }
 67 }
 68 void change(int x,int a,int b,ll c)
 69 {
 70     clean(x);
 71     if ((a<=l[x])&&(r[x]<=b))
 72     {
 73         v[x]=c;
 74         return;
 75     }
 76     int m=(l[x]+r[x])>>1;
 77     if (a<m)change(2*x,a,b,c);
 78     if (m<b)change(2*x+1,a,b,c);
 79     clean(2*x);clean(2*x+1);
 80     s[x]=min(s[2*x],s[2*x+1]);
 81 }
 82 ll query(int x,int a,int b)
 83 {
 84     clean(x);
 85     if ((a<=l[x])&&(r[x]<=b))
 86         return s[x];
 87     int m;
 88     ll ans=inf;
 89     m=(l[x]+r[x])>>1;
 90     if (a<m) ans=min(ans,query(2*x,a,b));
 91     if (m<b) ans=min(ans,query(2*x+1,a,b));
 92     return ans;
 93 }
 94 void gao(int a,int b,ll c)
 95 {
 96     while (1)
 97     {
 98         if (gf[a]==gf[b])
 99         {
100             if (deep[a]<deep[b]) a^=b^=a^=b;
101             change(1,L[b]-1,L[a],c);
102             return;
103         }
104         else
105         {
106             if (deep[gf[a]]<deep[gf[b]]) a^=b^=a^=b;
107             change(1,L[gf[a]]-1,L[a],c);
108             a=f[gf[a]];
109         }
110     }
111 }
112 int find(int x,int y)
113 {
114     int i;
115     for (i=17;i>=0;i--)
116     if (deep[jump[x][i]]>deep[y]) x=jump[x][i];
117     return x;
118 }
119 int main()
120 {
121     inf=1000000000;inf=inf*10;
122     scanf("%d%d",&n,&m);
123     for (i=1;i<n;i++)
124     {
125         scanf("%d%d",&a,&b);
126         link(a,b);link(b,a);
127     }
128     for (i=1;i<=n;i++)
129     scanf("%lld",&value[i]);
130     dfs1(1,0);
131     dfs2(1,1,0);
132     build(1,0,n);
133     scanf("%d",&root);
134     for (i=1;i<=m;i++)
135     {
136         scanf("%d",&typ);
137         if (typ==1) scanf("%d",&root);
138         else
139         if (typ==2)
140         {
141             scanf("%d%d%lld",&a,&b,&c);
142             gao(a,b,c);
143         }
144         else
145         {
146             scanf("%d",&a);
147             if (a==root)
148             printf("%lld\n",query(1,0,n));
149             else
150             if ((L[a]<=L[root])&&(R[root]<=R[a]))
151             {
152                 b=find(root,a);
153                 c=inf;
154                 if (L[b]-1>0) c=min(c,query(1,0,L[b]-1));
155                 if (R[b]<n) c=min(c,query(1,R[b],n));
156                 printf("%lld\n",c);
157             }
158             else
159             printf("%lld\n",query(1,L[a]-1,R[a]));
160         }
161     }
162 }

 

bzoj3083 遥远的国度

标签:

原文地址:http://www.cnblogs.com/fzmh/p/5424972.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!