• BZOJ 3653: 谈笑风生(DFS序+可持久化线段树)


    首先嘛,还是太弱了,想了好久QAQ 

    然后,这道题么,明显就是求sigma(size[x]) (x是y的儿子且层树小于k) 然后就可以发现:把前n个节点按深度建可持久化线段树,就能用前缀和维护了

    其实不难打= =

    #include<cstdio>

    #include<iostream>

    #include<cstring>

    #include<algorithm>

    using namespace std;

    #define maxn 300010

    #define maxm 30000100

    struct edges{

    int to,next;

    }edge[maxn*2];

    int next[maxn],l,num;

    int addedge(int x,int y){

    edge[++l]=(edges){x,next[y]};next[y]=l;

    edge[++l]=(edges){y,next[x]};next[x]=l;

    return 0;

    }

    int id[maxn],d[maxn],s[maxn],e[maxn],b[maxn];

    int dfs(int x,int y){

    id[++num]=x;

    d[x]=d[y]+1;

    b[x]=num;

    for (int i=next[x];i;i=edge[i].next){

    if (edge[i].to!=y) {

    dfs(edge[i].to,x);

    s[x]+=s[edge[i].to]+1;

    }

    }

    e[x]=num;

    return 0;

    }

    struct node{

    int lc,rc;long long s;

    }t[maxm];

    #define lc(x) t[x].lc

    #define rc(x) t[x].rc

    #define s(x) t[x].s

    #define mid ((l+r)>>1)

    int build(int x,int l,int r){

    if (l!=r) {

    lc(x)=build(++num,l,mid);

    rc(x)=build(++num,mid+1,r);

    }

    return x;

    }

    int ins(int x,int l,int r,int c,int z){

    int y=++num;

    if (l==r) {s(y)=s(x)+z;return y;}

    lc(y)=lc(x);rc(y)=rc(x);

    if (mid<c) rc(y)=ins(rc(x),mid+1,r,c,z);

    else lc(y)=ins(lc(x),l,mid,c,z);

    s(y)=s(lc(y))+s(rc(y));

    return y;

    }

    long long sum(int x,int l,int r,int x1,int y1){

    if (l>y1||r<x1) return 0;

    if (x1<=l&&r<=y1) return s(x);

    if (l==r) return s(x);

    return sum(lc(x),l,mid,x1,y1)+sum(rc(x),mid+1,r,x1,y1);

    }

    int root[maxn];

    int main(){

    int n,q;

    scanf("%d%d",&n,&q);

    for (int i=1;i<n;i++) {

    int x,y;

    scanf("%d%d",&x,&y);

    addedge(x,y);

    }

    dfs(1,0);

    num=0;l=0;

    root[0]=++num;

    build(1,1,n);

    for (int i=1;i<=n;i++)root[i]=ins(root[i-1],1,n,d[id[i]],s[id[i]]);

    for (int i=1;i<=q;i++) {

    int u,v;

    scanf("%d%d",&u,&v);

    printf("%lld ",s[u]*1ll*min(v,d[u]-1)+sum(root[e[u]],1,n,d[u]+1,d[u]+v)-sum(root[b[u]],1,n,d[u]+1,d[u]+v));

    }

    return 0;

    }


  • 相关阅读:
    SynchronousQueue 的联想
    Spring Cache
    CSUOJ 1011 Counting Pixels
    CSUOJ 1973 给自己出题的小X DFS
    CSUOJ 1726 你经历过绝望吗?两次!BFS+优先队列
    CSUOJ 1900 锋芒不露
    CSUOJ 1808 地铁
    CSUOJ 1895 Apache is late again
    CSUOJ 1781 阶乘除法
    CSUOJ 1560 图书管理员的表白方式
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4348916.html
Copyright © 2020-2023  润新知