zoukankan      html  css  js  c++  java
  • 【BZOJ3522&BZOJ4543】Hotel加强版(长链剖分,树形DP)

    题意:求一颗树上三点距离两两相等的三元组对数

    n<=1e5

    思路:From https://blog.bill.moe/bzoj4543-hotel/

    f[i][j]表示以i为根的子树中距离i为j的点的个数

    g[i][j]表示以i为根的子树中两点距离他们的lca为d,lca距离i为d-j的两点对数

    g[i][j]找到一个子树外的f[i][j]就对答案有贡献

    朴素的方程为:设v为u的一个儿子

    ans+=f[u][j]*g[v][j+1]+g[u][j]*f[y][j-1]

    g[u][j+1]+=f[u][j+1]*f[v][j]

    g[u][j-1]+=g[v][j]

    f[u][j+1]+=f[v][j]

    显然f[i][j]只和深度有关,且f[u]的[1,len[u]]这一段是所有f[v]的[0,len[u]-1]右移一位之和

    为了防止同一个子树中的信息算多了,先算ans部分再执行后面三步更新

    指针的写法我完全是抄的

      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  100010
     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-6;
     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 int head[M],vet[M],nxt[M],tot;
     34 int len[N],son[N];
     35 ll tmp[N*5],*f[N],*g[N],*now=tmp,ans;
     36 
     37 int read()
     38 {
     39    int v=0,f=1;
     40    char c=getchar();
     41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     43    return v*f;
     44 }
     45 
     46 void add(int a,int b)
     47 {
     48     nxt[++tot]=head[a];
     49     vet[tot]=b;
     50     head[a]=tot;
     51 }
     52 
     53 void dfs(int u,int fa,int d)
     54 {
     55     len[u]=0;
     56     int e=head[u];
     57     while(e)
     58     {
     59         int v=vet[e];
     60         if(v!=fa)
     61         {
     62             dfs(v,u,d+1);
     63             if(len[v]>len[son[u]])
     64             {
     65                 son[u]=v;
     66                 len[u]=len[v]+1;
     67             }
     68         }
     69         e=nxt[e];
     70     }
     71 }
     72 
     73 void solve(int u,int fa)
     74 {
     75     if(son[u])
     76     {
     77         f[son[u]]=f[u]+1;
     78         g[son[u]]=g[u]-1;
     79         solve(son[u],u);
     80     }
     81     f[u][0]=1;
     82     ans+=g[u][0];
     83     int e=head[u];
     84     while(e)
     85     {
     86         int v=vet[e];
     87         if(v!=fa&&v!=son[u])
     88         {
     89             f[v]=now;
     90             now+=(len[v]<<1)+2;
     91             g[v]=now;
     92             now+=(len[v]<<1)+2;
     93             solve(v,u);
     94             rep(j,0,len[v])
     95             {
     96                 if(j) ans+=f[u][j-1]*g[v][j];
     97                 ans+=g[u][j+1]*f[v][j];
     98             }
     99             rep(j,0,len[v])
    100             {
    101                 g[u][j+1]+=f[u][j+1]*f[v][j];
    102                 if(j) g[u][j-1]+=g[v][j];
    103                 f[u][j+1]+=f[v][j];
    104             }
    105         }
    106         e=nxt[e];
    107     }
    108 }
    109 int main()
    110 {
    111     int n=read();
    112     tot=0;
    113     rep(i,1,n-1)
    114     {
    115         int x=read(),y=read();
    116         add(x,y);
    117         add(y,x);
    118     }
    119     len[0]=-1;
    120     dfs(1,0,1);
    121     ans=0;
    122     f[1]=now,now+=(len[1]<<1)+2,g[1]=now,now+=(len[1]<<1)+2;
    123     solve(1,0);
    124     printf("%lld
    ",ans);
    125     return 0;
    126 }
  • 相关阅读:
    BZOJ 3132: 上帝造题的七分钟 树状数组+差分
    PAT Advanced 1006 Sign In and Sign Out (25 分)
    PAT Advanced 1011 World Cup Betting (20 分)
    PAT Basic 1032 挖掘机技术哪家强 (20 分)
    PAT Basic 1028 人口普查 (20 分)
    PAT Basic 1004 成绩排名 (20 分)
    大数据数据库HBase(二)——搭建与JavaAPI
    PAT Advanced 1009 Product of Polynomials (25 分)(vector删除元素用的是erase)
    PAT Advanced 1002 A+B for Polynomials (25 分)(隐藏条件,多项式的系数不能为0)
    PAT Basic 1041 考试座位号 (15 分)
  • 原文地址:https://www.cnblogs.com/myx12345/p/11568041.html
Copyright © 2011-2022 走看看