• 【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 }
  • 相关阅读:
    财务系统重复付款case分析及解决方案
    MySQL体系结构
    安装篇九:安装wordpress(5.4版本)
    安装篇八:配置 Nginx 使其支持 MySQL 应用
    安装篇七:配置 Nginx 使其支持 PHP 应用
    安装篇六:安装PHP(7.2.29版本)
    安装篇五:安装MySQL(5.6.38版本)
    安装篇四:安装NGINX(1.4.0版本)
    安装篇三:系统初始化设置
    安装篇二:CentOS 6.9系统安装
  • 原文地址:https://www.cnblogs.com/myx12345/p/11568041.html
Copyright © 2020-2023  润新知