zoukankan      html  css  js  c++  java
  • 【BZOJ1758】重建计划(点分治,长链剖分,线段树)

    题意:

    给定一棵n个点的树,每条边有权值。
    求一条链,这条链包含的边数在L和U之间,且平均边权最大。
    N﹤=100000

    思路:

    做法一:RYZ作业

    二分答案再点分治,寻找是否有大于0且边数在L和U之间的链

    f[i]为当前子树深度为i的链最大总和,g[i]为前几个深度为i的链最大总和

    维护一个下标递增,值递增的单调队列

    按子树深度排序一定要加,因为清空与当前子树深度最大值有关,不加的话可能会退化成n^2

    改了快一天改不出,还加了迭代,最后发现是分治的时候root打成v,相当于什么都没干……

      1 var head,vet,next,c,d,size,flag,q1:array[1..210000]of longint;
      2     p:array[0..210000]of longint;
      3     len,h,q2:array[1..210000]of double;
      4     f,g:array[0..210000]of double;
      5     n,i,tot,root,l1,r1,sum,mx,mxdep,x,y,z,tmp,t,w,now,m:longint;
      6     eps,oo,mid:double;
      7 
      8 procedure swap(var x,y:longint);
      9 var t:longint;
     10 begin
     11  t:=x; x:=y; y:=t;
     12 end;
     13 
     14 function max(x,y:longint):longint;
     15 begin
     16  if x>y then exit(x);
     17  exit(y);
     18 end;
     19 
     20 function min(x,y:longint):longint;
     21 begin
     22  if x<y then exit(x);
     23  exit(y);
     24 end;
     25 
     26 procedure add(a,b,c:longint);
     27 begin
     28  inc(tot);
     29  next[tot]:=head[a];
     30  vet[tot]:=b;
     31  len[tot]:=c;
     32  head[a]:=tot;
     33 end;
     34 
     35 procedure getroot(u,fa:longint);
     36 var e,v:longint;
     37 begin
     38  size[u]:=1; p[u]:=0;
     39  e:=head[u];
     40  while e<>0 do
     41  begin
     42   v:=vet[e];
     43   if (v<>fa)and(flag[v]=0) then
     44   begin
     45    getroot(v,u);
     46    size[u]:=size[u]+size[v];
     47    p[u]:=max(p[u],size[v]);
     48   end;
     49   e:=next[e];
     50  end;
     51  p[u]:=max(p[u],sum-p[u]);
     52  if p[u]<p[root] then root:=u;
     53 end;
     54 
     55 procedure dfs(u,fa,dep:longint;t:double);
     56 var e,v:longint;
     57 begin
     58  if f[dep]<t then f[dep]:=t;
     59  mx:=max(mx,dep);
     60  e:=head[u];
     61  while e<>0 do
     62  begin
     63   v:=vet[e];
     64   if (v<>fa)and(flag[v]=0) then dfs(v,u,dep+1,t+len[e]-mid);
     65   e:=next[e];
     66  end;
     67 
     68 end;
     69 
     70 procedure ins(k:longint;x:double);
     71 begin
     72  while (w>=t)and(q2[w]<x) do dec(w);
     73  inc(w); q1[w]:=k; q2[w]:=x;
     74 end;
     75 
     76 procedure del(k:longint);
     77 begin
     78  while (t<=w)and(q1[t]>=k) do inc(t);
     79 end;
     80 
     81 procedure getdep(u,fa,dep:longint);
     82 var e,v:longint;
     83 begin
     84  e:=head[u];
     85  if dep>d[m] then d[m]:=dep;
     86  while e<>0 do
     87  begin
     88   v:=vet[e];
     89   if (v<>fa)and(flag[v]=0) then getdep(v,u,dep+1);
     90   e:=next[e];
     91  end;
     92 end;
     93 
     94 procedure qsort(l,r:longint);
     95 var i,j,mid:longint;
     96     t:double;
     97 begin
     98  i:=l; j:=r; mid:=d[(l+r)>>1];
     99  repeat
    100   while mid>d[i] do inc(i);
    101   while mid<d[j] do dec(j);
    102   if i<=j then
    103   begin
    104    swap(d[i],d[j]);
    105    swap(c[i],c[j]);
    106    t:=h[i]; h[i]:=h[j]; h[j]:=t;
    107    inc(i); dec(j);
    108   end;
    109  until i>j;
    110  if l<j then qsort(l,j);
    111  if i<r then qsort(i,r);
    112 end;
    113 
    114 function solve(u:longint;avg:double):double;
    115 var t1,t2,ans,tmp:double;
    116     v,e,i,j:longint;
    117 begin
    118  t1:=avg; t2:=-oo;
    119  m:=0;
    120  e:=head[u];
    121  while e<>0 do
    122  begin
    123   v:=vet[e];
    124   if flag[v]=0 then
    125   begin
    126    inc(m);
    127    getdep(v,u,1);
    128    c[m]:=v; h[m]:=len[e];
    129   end;
    130   e:=next[e];
    131  end;
    132  if m>0 then qsort(1,m);
    133  while t1-t2>eps do
    134  begin
    135   t2:=t1; mid:=t1; ans:=-oo;
    136   mxdep:=0; g[0]:=0;
    137   for j:=1 to m do
    138   begin
    139    v:=c[j];
    140    mx:=0;
    141    dfs(v,u,1,h[j]-mid);
    142    t:=1; w:=0;
    143    for i:=min(mxdep,r1) to l1 do ins(i,g[i]);
    144    for i:=max(1,l1-mxdep) to mx do
    145    begin
    146     if l1-i>=0 then ins(l1-i,g[l1-i]);
    147     del(r1-i+1);
    148     if t<=w then
    149      if (f[i]+q2[t])/(q1[t]+i)>ans then
    150       ans:=(f[i]+q2[t])/(q1[t]+i);
    151    end;
    152    mxdep:=max(mxdep,mx);
    153    for i:=0 to mx do
    154     if f[i]>g[i] then g[i]:=f[i];
    155    for i:=0 to mx do f[i]:=-oo;
    156   end;
    157   for i:=0 to mxdep do g[i]:=-oo;
    158   t1:=t1+ans;
    159  end;
    160  flag[u]:=1; t2:=t1;
    161  e:=head[u];
    162  while e<>0 do
    163  begin
    164   v:=vet[e];
    165   if flag[v]=0 then
    166   begin
    167    root:=0; sum:=size[v];
    168    getroot(v,0);
    169    tmp:=solve(root,t1);
    170    if tmp>t2 then t2:=tmp;
    171   end;
    172   e:=next[e];
    173  end;
    174  exit(t2);
    175 
    176 end;
    177 
    178 begin
    179  assign(input,'bzoj1758.in'); reset(input);
    180  assign(output,'bzoj1758.out'); rewrite(output);
    181  readln(n);
    182  readln(l1,r1);
    183  oo:=1e8;
    184  for i:=1 to n-1 do
    185  begin
    186   readln(x,y,z);
    187   add(x,y,z);
    188   add(y,x,z);
    189  end;
    190  p[0]:=n+1; root:=0; sum:=n;
    191  eps:=1e-4;
    192  getroot(1,0);
    193  for i:=0 to n do
    194  begin
    195   f[i]:=-oo; g[i]:=-oo;
    196  end;
    197  writeln(solve(root,0):0:3);
    198  close(input);
    199  close(output);
    200 end.

     做法2:From https://blog.bill.moe/WC2010-rebuild/

    建立一个答案表,顺序是长链剖分的dfs序

    长链可以共用答案表,轻儿子暴力合并到父亲所在长链中

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef pair<int,int> PII;
      7 typedef pair<ll,ll> Pll;
      8 typedef vector<int> VI;
      9 typedef vector<PII> VII;
     10 typedef pair<ll,int>P;
     11 #define N  200010
     12 #define M  200010
     13 #define fi first
     14 #define se second
     15 #define MP make_pair
     16 #define pi acos(-1)
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     20 #define lowbit(x) x&(-x)
     21 #define Rand (rand()*(1<<16)+rand())
     22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     23 #define ls p<<1
     24 #define rs p<<1|1
     25 
     26 const ll MOD=1e9+7,inv2=(MOD+1)/2;
     27       double eps=1e-4;
     28       int INF=1<<30;
     29       ll inf=5e13;
     30       int dx[4]={-1,1,0,0};
     31       int dy[4]={0,0,-1,1};
     32 
     33 double t[N<<2];
     34 int head[N],vet[N],len[N],nxt[N],
     35     dep[N],son[N],slen[N],fa[N],id[N],dfn[N],mx[N],top[N],
     36     tot,L,R,tim,n;
     37 double ans,tmp[N];
     38 
     39 int read()
     40 {
     41    int v=0,f=1;
     42    char c=getchar();
     43    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     44    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     45    return v*f;
     46 }
     47 
     48 void add(int a,int b,int c)
     49 {
     50     nxt[++tot]=head[a];
     51     vet[tot]=b;
     52     len[tot]=c;
     53     head[a]=tot;
     54 }
     55 
     56 void build(int l,int r,int p)
     57 {
     58     t[p]=-1e18;
     59     if(l==r)
     60     {
     61         id[l]=p;
     62         return;
     63     }
     64     int mid=(l+r)>>1;
     65     build(l,mid,ls);
     66     build(mid+1,r,rs);
     67 }
     68 
     69 void update(int u,double v)
     70 {
     71     int now=id[u];
     72     while(now)
     73     {
     74         t[now]=max(t[now],v);
     75         now>>=1;
     76     }
     77 }
     78 
     79 double query(int l,int r,int x,int y,int p)
     80 {
     81     if(x<=l&&r<=y) return t[p];
     82     int mid=(l+r)>>1;
     83     double res=-1e18;
     84     if(x<=mid) res=max(res,query(l,mid,x,y,ls));
     85     if(y>mid) res=max(res,query(mid+1,r,x,y,rs));
     86     return res;
     87 }
     88 
     89 void dfs1(int u,int pre,int d)
     90 {
     91     dep[u]=mx[u]=d;
     92     fa[u]=pre;
     93     int e=head[u];
     94     while(e)
     95     {
     96         int v=vet[e];
     97         if(v!=pre)
     98         {
     99             dfs1(v,u,d+1);
    100             if(mx[v]>mx[son[u]])
    101             {
    102                 son[u]=v;
    103                 slen[u]=len[e];
    104                 mx[u]=mx[v];
    105             }
    106         }
    107         e=nxt[e];
    108     }
    109 }
    110 
    111 void dfs2(int u,int ance)
    112 {
    113     top[u]=ance;
    114     dfn[u]=++tim;
    115     if(son[u]) dfs2(son[u],ance);
    116     int e=head[u];
    117     while(e)
    118     {
    119         int v=vet[e];
    120         if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
    121         e=nxt[e];
    122     }
    123 }
    124 
    125 double ask(int u,int l,int r)
    126 {
    127     l=max(l,0);
    128     r=min(r,mx[u]-dep[u]);
    129     if(l>r) return -1e18;
    130     return query(1,n,dfn[u]+l,dfn[u]+r,1);
    131 }
    132 
    133 void solve(int u,double d,double mid)
    134 {
    135     update(dfn[u],d);
    136     if(son[u]) solve(son[u],d+slen[u]-mid,mid);
    137     int e=head[u];
    138     while(e)
    139     {
    140         int v=vet[e];
    141         if(v!=fa[u]&&v!=son[u])
    142         {
    143             solve(v,d+len[e]-mid,mid);
    144             rep(j,1,mx[v]-dep[v]+1)
    145             {
    146                 tmp[j]=t[id[dfn[v]+j-1]];
    147                 ans=max(ans,tmp[j]+ask(u,L-j,R-j)-2*d);
    148             }
    149             rep(j,1,mx[v]-dep[v]+1) update(dfn[u]+j,tmp[j]);
    150         }
    151         e=nxt[e];
    152     }
    153     ans=max(ans,ask(u,L,R)-d);
    154 }
    155 
    156 int isok(double K)
    157 {
    158     build(1,n,1);
    159     ans=-1e18;
    160     solve(1,0,K);
    161     return ans>=-eps;
    162 }
    163 
    164 int main()
    165 {
    166     n=read(),L=read(),R=read();
    167     tot=0;
    168     rep(i,1,n-1)
    169     {
    170         int x=read(),y=read(),z=read();
    171         add(x,y,z);
    172         add(y,x,z);
    173     }
    174     dfs1(1,0,1);
    175     tim=0;
    176     dfs2(1,1);
    177     double left=0,right=1e10;
    178     while(right-left>eps)
    179     {
    180         double mid=(left+right)/2;
    181         if(isok(mid)) left=mid;
    182          else right=mid;
    183     }
    184     printf("%.3f
    ",left);
    185     return 0;
    186 }
  • 相关阅读:
    JavaWeb学习篇之----自定义标签&&JSTL标签库详解
    JavaWeb学习篇之----EL表达式详解
    JavaWeb学习篇之----Jsp详解
    JavaWeb学习篇之----Servlet过滤器Filter和监听器
    JavaWeb学习篇之----Session&&Cookie
    JavaWeb学习篇之----容器Request详解
    JavaWeb学习篇之----浏览器缓存问题详解
    JavaWeb学习篇之----容器Response详解
    JavaWeb学习篇之----HTTP协议详解
    factory工厂模式之抽象工厂AbstractFactory
  • 原文地址:https://www.cnblogs.com/myx12345/p/6543153.html
Copyright © 2011-2022 走看看