[BZOJ3653][长链剖分]谈笑风生
生活随笔
收集整理的這篇文章主要介紹了
[BZOJ3653][长链剖分]谈笑风生
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
BZOJ3653
我也不知道題面的引申意義
發(fā)現(xiàn)可以求出以每個(gè)點(diǎn)為p時(shí)的ans,討論一下祖先和子孫的貢獻(xiàn),用長(zhǎng)鏈剖分維護(hù)就好了
Code:
#include<bits/stdc++.h> #define ll long long using namespace std; inline int read(){int res=0,f=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}return res*f; } const int N=3e5+5; int vis[N<<1],nxt[N<<1],head[N<<1],tot=0; int val[N],pt[N],fa[N],lson[N],top[N],md[N],dep[N],siz[N]; ll tmp[N],*f[N],*id=tmp,ans[N]; struct Q{int num,k;}; vector<Q>q[N]; inline void add(int x,int y){vis[++tot]=y;nxt[tot]=head[x];head[x]=tot;} void dfs(int v){pt[v]=siz[v]=1;for(int i=head[v];i;i=nxt[i]){int y=vis[i];if(pt[y]) continue;fa[y]=v;md[y]=dep[y]=dep[v]+1;dfs(y);siz[v]+=siz[y];if(md[y]>md[lson[v]]) lson[v]=y;}if(lson[v]) md[v]=md[lson[v]]; } void dp(int v){f[v][0]=siz[v]-1;if(lson[v]) f[lson[v]]=f[v]+1,dp(lson[v]),f[v][0]+=f[lson[v]][0];for(int i=head[v];i;i=nxt[i]){int y=vis[i];if(y==fa[v] || y==lson[v]) continue;f[y]=id;id+=md[y]-dep[y]+1;dp(y);for(int j=0;j<=md[y]-dep[y];j++) f[v][j+1]+=f[y][j];f[v][0]+=f[y][0];}for(int i=q[v].size()-1;~i;i--){int k=q[v][i].k,num=q[v][i].num;ans[num]+=1ll*(siz[v]-1)*min(dep[v]-1,k);if(k>=md[v]-dep[v]) ans[num]+=f[v][0]-siz[v]+1;else ans[num]+=f[v][0]-siz[v]+1-f[v][k+1];}return; } int n,m; int main(){n=read(),m=read();for(int x,y,i=1;i<n;i++){x=read(),y=read();add(x,y);add(y,x);}dep[1]=1;dfs(1);for(int i=1;i<=m;i++) {int u=read();Q t;t.k=read();t.num=i;q[u].push_back(t);}f[1]=id;id+=md[1];dp(1);for(int i=1;i<=m;i++) cout<<ans[i]<<"\n";return 0; }總結(jié)
以上是生活随笔為你收集整理的[BZOJ3653][长链剖分]谈笑风生的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Coordinatorlayout嵌套滑
- 下一篇: pkg提取