• COGS 2551. 新型武器


    【问题描述】

    给一包含 N 个节点的树,以 1 号点为根。 求 u 号点的子树上,在子树中深度为 c 的点的权值和(u 号点深度为 0)。 包含权值修改操作。

    【输入格式】

    输入共 N+Q+2 行。

    第 1 行包含 1 个正整数 N,表示共有 N 个节点。
    第 2 行包含 N 个由空格隔开的非负的整数 V1, V2, V3 ... VN,其中 Vi 表示编号为 i 的点的权值。
    第 2 +(1) 至 2 +(N-1) 行,每行包含 2 个正整数 fr,to,表示一边连接 fr,to 两点。
    第 N+2 行包含 1 个正整数 Q,表示接下来共有 Q 个 修改 / 询问。
    第 N+2 +(1) 至 N+2 +(Q) 行,每行包含 1 个 修改 / 询问。

    修改 格式:
    1 u v
    表示将 u 号点的权值改为 v。

    询问 格式:
    2 u c 求 u 号点的子树上,在子树中深度为 c 的点的权值和(u 号点深度为 0)。

    【输出格式】

    输出多行(<= Q)。

    每行包含 1 个非负的整数,表示其对应 询问 的答案,按照输入的先后顺序依次回答。

    【样例输入】

    7
    1 1 1 1 1 1 1
    1 2
    1 3
    2 7
    3 4
    3 6
    4 5
    7
    2 1 1
    2 1 2
    2 3 6
    1 4 5
    2 4 0
    2 1 2
    2 3 1

    【样例输出】

    2
    3
    0
    5
    7
    6

    【数据规模与约定】


     对于全部测试点:
    编号为 1 的点是根; fa 是 to 的父亲节点; to > fa; to - fa <= 50
    0 <= Vi <= 3000; 0 <= v <= 3000
    c < N

    题解:

      这个题目先将我的做法吧!

      我们对于每个点求出他的dfn,deep,和子树内节点的最大的dfn(记为ed)。

      我们对于每个点,将他们按照dep作为第一关键字,dfn作为第二关键子排序,对于deep相同的点,他们在线段树中的位置一定连续,并且满足dfn递增的,我们把这些节点按顺序插到线段树之中去,那么我们要统计的一定是连续的一段区间,所以对于一个点我们要判断他十分在子树内只需要判断他的dfn十分>=dfn[x]&&<=ed[x],所以我们二分出满足条件的区间的左右断点,线段树查询就行了,修改是一样的。

      还有一个比较好想的做法,就是开深度棵线段树,查询也是一样的,只不过要动态开点,代码是LJ的,也提供作为参考。

    代码:算法1

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #define MAXN 300100
    using namespace std;
    struct edge{
        int first,next,to;
    }a[MAXN*2];
    struct tree{
        int l,r,zhi;
    }tr[MAXN*4];
    struct no{
        int dfn,dep,v;
    }node[MAXN*2];
    int dep[MAXN],dfn[MAXN],ed[MAXN],v[MAXN];
    int depl[MAXN],depr[MAXN];
    int n,q,num=0;
    
    void addedge(int from,int to){
        a[++num].to=to;
        a[num].next=a[from].first;
        a[from].first=num;
    }
    
    void dfs1(int now,int f){
        dep[now]=dep[f]+1,dfn[now]=++num;
        for(int i=a[now].first;i;i=a[i].next){
            int to=a[i].to;
            if(to==f) continue;
            dfs1(to,now);
            ed[now]=max(ed[now],ed[to]);
        }
        ed[now]=max(ed[now],dfn[now]);
    }
    
    bool cmp(no x,no y){
        if(x.dep==y.dep) return x.dfn<y.dfn;
        return x.dep<y.dep;
    }
    
    int erfen(int hh,int l,int r){
        int mid,ans=-1;
        while(l<=r){
            mid=(l+r)/2;
            if(node[mid].dfn>=hh) ans=mid,r=mid-1;
            else l=mid+1;
        }
        return ans;
    }
    
    int erfen2(int l,int r,int minn,int maxx){
        int mid,ans=-1;
        while(l<=r){
            mid=(l+r)/2;
            if(node[mid].dfn<minn) l=mid+1;
            else if(node[mid].dfn>maxx) r=mid-1;
            else ans=mid,r=mid-1;
        }
        return ans;
    }
    
    int erfen3(int l,int r,int minn,int maxx){
        int mid,ans=-1;
        while(l<=r){
            mid=(l+r)/2;
            if(node[mid].dfn<minn) l=mid+1;
            else if(node[mid].dfn>maxx) r=mid-1;
            else ans=mid,l=mid+1;
        }
        return ans;
    }
    
    void build(int xv,int l,int r){
        if(l==r){
            tr[xv].l=tr[xv].r=l;
            tr[xv].zhi=node[l].v;
            return;
        }
        tr[xv].l=l,tr[xv].r=r;
        int mid=(l+r)/2;
        build(xv*2,l,mid),build(xv*2+1,mid+1,r);
        tr[xv].zhi=tr[xv*2].zhi+tr[xv*2+1].zhi;
    }
    
    void change(int xv,int ps,int x){
        int l=tr[xv].l,r=tr[xv].r,mid=(l+r)/2;
        if(l==r){
            tr[xv].zhi=x;
            return;
        }
        if(ps<=mid) change(xv*2,ps,x);
        else change(xv*2+1,ps,x);
        tr[xv].zhi=tr[xv*2].zhi+tr[xv*2+1].zhi;
    }
    
    int query(int xv,int l,int r){
        int L=tr[xv].l,R=tr[xv].r,mid=(L+R)/2;
        if(L==l&&r==R){
            return tr[xv].zhi;
        }
        if(r<=mid) return query(xv*2,l,r);
        else if(l>mid) return query(xv*2+1,l,r);
        else return query(xv*2,l,mid)+query(xv*2+1,mid+1,r);
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&v[i]);
        for(int i=1;i<=n-1;i++){
            int x,y;scanf("%d%d",&x,&y);
            addedge(x,y),addedge(y,x);
        }
        num=0;dfs1(1,0);
        for(int i=1;i<=n;i++) node[i].dfn=dfn[i],node[i].dep=dep[i],node[i].v=v[i];
        sort(node+1,node+n+1,cmp);
        memset(depl,127,sizeof(depl));
        for(int i=1;i<=n;i++){
            depl[node[i].dep]=min(depl[node[i].dep],i);
            depr[node[i].dep]=max(depr[node[i].dep],i);
        }
        build(1,1,n);
        scanf("%d",&q);
        while(q--){
            int id,x,y;scanf("%d%d%d",&id,&x,&y);
            if(id==1){
                int ps=erfen(dfn[x],depl[dep[x]],depr[dep[x]]);
                change(1,ps,y);
            }
            else{
                int deep=dep[x]+y;
                int ll=erfen2(depl[deep],depr[deep],dfn[x],ed[x]),rr=erfen3(depl[deep],depr[deep],dfn[x],ed[x]);
                if(ll==-1||rr==-1){
                    printf("0
    ");continue;
                }
                printf("%d
    ",query(1,ll,rr));
            }
        }
        return 0;
    }

    代码:算法2

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<map>
    #define ls k<<1
    #define rs k<<1|1
    #define RG register
    #define MAXN 400010
    #define LL long long int
    using namespace std;
    const int INF=1e9;
    struct node{
        int next;
        int to;
    }t[MAXN*2];
    int head[MAXN*2],num;
    int n,m;
    int sum[MAXN*20],lson[MAXN*20],rson[MAXN*20];
    int val[MAXN];
    int dfn[MAXN],low[MAXN],dep[MAXN],tot;
    int root[MAXN],sz;
    void add(int from,int to)
    {
        t[++num].next=head[from];
        t[num].to=to;
        head[from]=num;
    }
    void dfs(int u,int f,int k)
    {
        dfn[u]=++tot;dep[u]=k;
        for(int i=head[u];i;i=t[i].next)
            {
                int v=t[i].to;
                if(v==f) continue;
                dfs(v,u,k+1);
            }
        low[u]=tot;
    }
    void update(int L,int R,int id,int x,int &k)
    {
        if(!k) k=++sz;
        if(L==R){sum[k]=x;return;}
        int mid=(L+R)>>1;
        if(id<=mid) update(L,mid,id,x,lson[k]);
        else update(mid+1,R,id,x,rson[k]);
        sum[k]=sum[lson[k]]+sum[rson[k]];
    }
    int query(int L,int R,int l,int r,int k)
    {
        if(!k) return 0;
        if(l<=L&&R<=r) return sum[k];
        int mid=(L+R)>>1;
        if(r<=mid)  return query(L,mid,l,r,lson[k]);
        else{
            if(l>mid) return query(mid+1,R,l,r,rson[k]);
            else return query(L,mid,l,mid,lson[k])+query(mid+1,R,mid+1,r,rson[k]);
        }
    }
    int main()
    { 
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&val[i]);
        int x,y;
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);add(x,y);add(y,x);
        }
        dfs(1,0,1);
        for(int i=1;i<=n;i++) update(1,n,dfn[i],val[i],root[dep[i]]);
        scanf("%d",&m);
        int ch,c1,c2;
        for(int i=1;i<=m;i++)
            { 
                scanf("%d%d%d",&ch,&c1,&c2);
                if(ch==1) update(1,n,dfn[c1],c2,root[dep[c1]]);
                else  printf("%d
    ",query(1,n,dfn[c1],low[c1],root[dep[c1]+c2]));
            }
        return 0;
    }
  • 相关阅读:
    So sad! ,Asphyre Closure
    Asphyre Sphinx is a cross-platform framework for developing 2D/3D video games and interactive business applications
    Mark: admob for delphi xe4 integrated 80% -done!-95% to do more test
    CCBPM新手流程设计教程
    CCBPM 常用API接口说明
    CCBPM H5版本中组织结构集成以及与外部数据源同步介绍
    关于驰骋工作流引擎ccbpm 在工业自动化环境下的应用演示实例
    关于驰骋工作流引擎ccbpm 在工业自动化环境下的 应用演示实例
    CCFlow新版本的自由流程、自定义流程功能说明
    关于驰骋工作流引擎ccbpm对bpmn2.0的支持
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7655925.html
Copyright © 2020-2023  润新知