zoukankan      html  css  js  c++  java
  • [bzoj3611][Heoi2014]大工程

      看题目感觉应该就是传说中的虚树?

      然后跑去学了一发。。。自己YY了一下然后挂飞。。于是就只好抄模板了T_T

      建完虚树就是个树形dp。。。

      对于询问总和:每条边对答案的贡献是边权*一端的节点数*另一端的节点数。(这里的节点不包括建虚树时添上去的点)

      对于询问最小值最大值,每次计算出经过这个节点的最长||最短路径长度就好了。。

      大概这种题条件都有一个sigma(K)<=n之类的。。而且题目求的东西得符合区间加法。。。不然你把边合在一起也没用>_<

      链剖求lca果然快。。。速度能进前10.。。然而代码长度实在感人= =

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define ll long long
      6 using namespace std;
      7 const int maxn=1000023;
      8 const int inf=1002333333;
      9 struct zs{
     10     int too,pre;
     11 }e[maxn<<1];
     12 struct zs1{
     13     int too,pre,dis;
     14 }e1[maxn<<2];
     15 int tot,tot1,last[maxn],last1[maxn];
     16 int sz[maxn],mn[maxn],mx[maxn];
     17 int intree[maxn],poi[maxn],rt;
     18 int dfn[maxn],bel[maxn],size[maxn],dep[maxn],fa[maxn],tim;
     19 int st[maxn],top;
     20 int ansmn,ansmx;
     21 ll anssum;
     22 int i,j,k,n,m,K,a,b,lca;
     23  
     24  
     25 int ra;char rx;
     26 inline int read(){
     27     rx=getchar(),ra=0;
     28     while(rx<'0'||rx>'9')rx=getchar();
     29     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
     30 }
     31  
     32  
     33 inline void insert(int a,int b){
     34     e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;
     35     e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
     36 }
     37 inline void ins(int a,int b){
     38 //  printf("   %d-->%d
    ",a,b);
     39     e1[++tot1].too=b,e1[tot1].dis=dep[b]-dep[a],e1[tot1].pre=last1[a],last1[a]=tot1;
     40 }
     41  
     42  
     43 void dfs1(int x){
     44     size[x]=1;
     45     for(int i=last[x];i;i=e[i].pre)
     46         if(e[i].too!=fa[x])
     47             fa[e[i].too]=x,
     48             dfs1(e[i].too),
     49             size[x]+=size[e[i].too];
     50 }
     51 void dfs2(int x,int chain){
     52     bel[x]=chain,dfn[x]=++tim,dep[x]=dep[fa[x]]+1;int mxpos=0,i,to;
     53     for(to=e[i=last[x]].too;i;to=e[i=e[i].pre].too)
     54         if(to!=fa[x]&&size[to]>size[mxpos])mxpos=to;
     55     if(!mxpos)return;
     56     dfs2(mxpos,chain);
     57     for(to=e[i=last[x]].too;i;to=e[i=e[i].pre].too)
     58         if(to!=fa[x]&&to!=mxpos)dfs2(to,to);
     59 }
     60 inline int getlca(int a,int b){
     61     if(dep[bel[a]]<dep[bel[b]])swap(a,b);
     62     while(bel[a]!=bel[b]){
     63         a=fa[bel[a]];
     64         if(dep[bel[a]]<dep[bel[b]])swap(a,b);
     65     }
     66     return dep[a]<dep[b]?a:b;
     67 }
     68  
     69  
     70 bool cmp(int a,int b){return dfn[a]<dfn[b];}
     71  
     72 inline int min(int a,int b){return a<b?a:b;}
     73 inline int max(int a,int b){return a>b?a:b;}
     74 void dp(int x){
     75     register int i,to;
     76     if(intree[x]==m)sz[x]=1,mn[x]=mx[x]=0;
     77         else sz[x]=0,mn[x]=inf,mx[x]=-inf;
     78     for(to=e1[i=last1[x]].too;i;to=e1[i=e1[i].pre].too){
     79         dp(to),sz[x]+=sz[to],mn[to]+=e1[i].dis,mx[to]+=e1[i].dis;
     80         anssum+=(ll)sz[to]*(K-sz[to])*e1[i].dis;
     81         if(mn[x]+mn[to]<ansmn)ansmn=mn[x]+mn[to];
     82         if(mx[to]+mx[x]>ansmx)ansmx=mx[x]+mx[to];
     83         if(mn[to]<mn[x])mn[x]=mn[to];if(mx[to]>mx[x])mx[x]=mx[to];
     84     }
     85     last1[x]=0;
     86 }
     87  
     88  
     89 char s[23];int len;
     90 inline void outll(ll x){
     91     if(!x){putchar('0');return;}
     92     for(len=0;x;s[++len]=x%10,x/=10);
     93     while(len)putchar(s[len--]+48);
     94 }
     95 inline void outint(int x){
     96     if(!x){putchar('0');return;}
     97     for(len=0;x;s[++len]=x%10,x/=10);
     98     while(len)putchar(s[len--]+48);
     99 }
    100  
    101  
    102 int main(){
    103     register int i;
    104     n=read();
    105     for(i=1;i<n;i++)a=read(),b=read(),insert(a,b);
    106     dfs1(1),dfs2(1,1);
    107 //  for(i=1;i<=n;i++)printf("  %d  %d
    ",dep[i],dfn[i]);
    108 //  for(i=1;i<n;i++)for(j=i+1;j<=n;j++)printf("  %d&&%d %d
    ",i,j,getlca(i,j));
    109     for(m=read();m;m--){
    110         tot1=0;
    111         for(K=read(),i=1;i<=K;i++)intree[poi[i]=read()]=m;
    112         sort(poi+1,poi+1+K,cmp);top=1,st[1]=poi[1];
    113 //      for(i=1;i<=K;i++)printf("  %d
    ",poi[i]);
    114         for(i=2;i<=K;i++){
    115             lca=getlca(poi[i],st[top]);
    116             while(dfn[lca]<dfn[st[top]]&&top)
    117                 if(dfn[st[top-1]]<=dfn[lca]){
    118                     ins(lca,st[top--]);
    119                     if(st[top]!=lca)st[++top]=lca;
    120                 }else ins(st[top-1],st[top]),top--;
    121             st[++top]=poi[i];
    122         }
    123         while(top>1)ins(st[top-1],st[top]),top--;
    124         ansmn=inf,ansmx=anssum=0,rt=st[1],
    125         dp(rt);
    126         outll(anssum),putchar(' '),outint(ansmn),putchar(' '),outint(ansmx),putchar('
    ');
    127     }
    128     return 0;
    129 }
    View Code
  • 相关阅读:
    AppleID的双重认证
    swift 分组tableview 设置分区投或者尾部,隐藏默认间隔高度
    swift 警告框
    数组
    循环结构(二)
    循环结构
    选择结构
    选择结构
    变量 数据类型和运算符
    (五)Spring 中的 aop
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5187230.html
Copyright © 2011-2022 走看看