hdu5156 Harry and Christmas tree 离线树状数组,dfs序

来源:互联网 发布:海信电视直播软件安装 编辑:程序博客网 时间:2024/06/01 09:02

题意:一棵树上每个节点有一些不同颜色的礼物,求每棵子树礼物的颜色数。

parse:dfs序处理后相当于询问一些区间的颜色数,树状数组离线解决,详情见代码,很巧妙。

#include<iostream>#include<cstring>#include<cstdio>#include<ostream>#include<istream>#include<algorithm>#include<queue>#include<string>#include<cmath>#include<set>#include<map>#include<stack>#include<vector>#define fi first#define se second#define ll long long#define pii pair<int,int>#define inf (1<<30)#define eps 1e-8#define pb push_backusing namespace std;const int maxn=110005;int n,m;vector<int>g[maxn];vector<int>col[maxn];int l[maxn],r[maxn];int last[maxn];int sum[maxn];int p[maxn];int ans[maxn];int dfs_clock;struct Node{    int l,r,id;}node[maxn];void dfs(int u,int fa){    l[u]=++dfs_clock;    p[dfs_clock]=u;    for(int i=0;i<g[u].size();i++) {        if(g[u][i]==fa)            continue;        dfs(g[u][i],u);    }    r[u]=dfs_clock;}bool cmp(const Node& u,const Node& v){    return u.r<v.r;}int lowbit(int x){    return x&-x;}int Sum(int x){    int tot=0;    while(x>0) {        tot+=sum[x];        x-=lowbit(x);    }    return tot;}void update(int x,int d){    while(x<=n) {        sum[x]+=d;        x+=lowbit(x);    }}int main(){    int a,b;    while(~scanf("%d%d",&n,&m)) {        for(int i=1;i<=n;i++) {            sum[i]=0;            g[i].clear();            col[i].clear();        }        for(int i=0;i<n-1;i++) {            scanf("%d%d",&a,&b);            g[a].push_back(b);            g[b].push_back(a);        }        for(int i=0;i<m;i++) {            scanf("%d%d",&a,&b);            col[a].push_back(b);            last[b]=-1;        }        dfs_clock=0;        dfs(1,-1);        for(int i=1;i<=n;i++) {            node[i].l=l[i];            node[i].r=r[i];            node[i].id=i;        }        sort(node+1,node+n+1,cmp);        int j=1;        for(int i=1;i<=n;i++) {            while(j<=node[i].r) {                for(int k=0;k<col[p[j]].size();k++) {                    int c=col[p[j]][k];                    if(last[c]!=-1) update(last[c],-1);                    update(j,1);                    last[c]=j;                }                j++;            }            ans[node[i].id]=Sum(node[i].r)-Sum(node[i].l-1);        }        printf("%d",ans[1]);        for(int i=2;i<=n;i++)            printf(" %d",ans[i]);        puts("");    }    return 0;}


0 0
原创粉丝点击