• 华华和月月种树


    题目链接:https://ac.nowcoder.com/acm/contest/392/H

    作者:fzszkl
    链接:https://ac.nowcoder.com/discuss/160376?type=101&order=time&pos=&page=1
    来源:牛客网

    首先离线操作,建出整棵树的最终状态。对这棵树进行DFS,i号点被搜到的时间记为DFNiDFNi。DFN有一个重要的性质,就是同一棵子树内的节点的DFN总是连续的,所以我们可以用一个线段树按照DFN的顺序来维护所有点的点权。

    考虑到一个操作会影响到一个点有以下两个条件:1、被操作的是被影响的点的祖先(或它自己);2、加点的时间早于操作的时间。

    所以我们执行修改和询问时直接对整棵子树执行,执行加点操作的时候直接将这个点当前的点权**清零**即可。这样可以消除所有早于它出现的操作的影响。因为只有单点询问,所以本题线段树可用差分树状数组代替。时间复杂度O(MlogM)O(Mlog⁡M)。

    #include <bits/stdc++.h>
    using namespace std;
    #define re register
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    const int maxn=1e5+10;
    void read(int &a)
    {
        a=0;
        int d=1;
        char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch-'0';
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=a*10+ch-'0';
        a*=d;
    }
    void write(int x)
    {
        if(x<0)
            putchar(45),x=-x;
        if(x>9)
            write(x/10);
        putchar(x%10+'0');
    }
    struct note
    {
        int op,a,x,asd;
    }tmp[4*maxn];
    int cnt[maxn],cnt_end[maxn],t,tree[maxn],n;
    vector <int> q[maxn];
    void dfs(int x)
    {
        cnt[x]=++t;
        for(re int i=0;i<q[x].size();i++)
            dfs(q[x][i]);
        cnt_end[x]=t;
    }
    int lowbit(int k)
    {
        return k&-k;
    }
    void add(int i,int x)
    {
        while(i<=t)
        {
            tree[i]+=x;
            i+=lowbit(i);
        }
    }
    void add1(int l,int r,int x)
    {
        add(l,x);
        add(r+1,-x);
    }
    ll sum(int i)
    {
        ll ans=0;
        while(i)
        {
            ans+=tree[i];
            i-=lowbit(i);
        }
        return ans;
    }
    int main()
    {
        int T;
        read(T);
        for(re int i=1;i<=T;i++)
        {
            read(tmp[i].op);
            read(tmp[i].a);
            if(tmp[i].op==1)
            {
                q[tmp[i].a].pb(++n);
                tmp[i].asd=n;
            }
            else if(tmp[i].op==2)
                read(tmp[i].x);
        }
        dfs(0);
        for(re int i=1;i<=T;i++)
        {
            if(tmp[i].op==1)
            {
                int val=sum(cnt[tmp[i].asd]);
                add1(cnt[tmp[i].asd],cnt[tmp[i].asd],-val);
            }
            else if(tmp[i].op==2)
                add1(cnt[tmp[i].a],cnt_end[tmp[i].a],tmp[i].x);
            else
                printf("%lld
    ",sum(cnt[tmp[i].a]));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    一月份阅读笔记3
    python条件判断语句之if else elif
    2021年
    软件架构分析
    Python之元组(Tuple)
    python之列表(list)
    python之字符串
    python学习
    如何应对日新月异的IT服务管理(ITSM)
    springboot 实现递归查询菜单
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/10668064.html
Copyright © 2020-2023  润新知