zoukankan      html  css  js  c++  java
  • P3258 [JLOI2014]松鼠的新家

    题目链接:

    树链剖分裸题emmm写了这么多道好像道道都是裸题

    #pragma GCC optimize("O3")
    #include <bits/stdc++.h>
    #include <tr1/unordered_map>
    using namespace std;
    #define ll long long
    #define re register
    #define pb push_back
    #define fi first
    #define se second
    const int N=1e6+10;
    const int mod=998244353;
    void read(int &a)
    {
        a=0;int d=1;char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch^48;
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=(a<<3)+(a<<1)+(ch^48);
        a*=d;
    }
    int a[N],top[N],id[N],siz[N],son[N],dep[N],f[N],cnt,rt=1;
    vector <int> v[N];
    struct note{int l,r,lazy;ll sum;}tree[N<<1];
    void dfs1(int x)
    {
        siz[x]=1,dep[x]=dep[f[x]]+1;
        for(auto i:v[x])
        {
            if(i!=f[x])
            {
                f[i]=x,dfs1(i);
                siz[x]+=siz[i];
                if(siz[son[x]]<siz[i]) son[x]=i;
            }
        }
    }
    void dfs2(int x,int tp)
    {
        top[x]=tp,id[x]=++cnt;
        if(son[x]) dfs2(son[x],tp);
        for(auto i:v[x]) if(i!=f[x]&&i!=son[x]) dfs2(i,i);
    }
    void build(int l,int r,int now)
    {
        tree[now].l=l,tree[now].r=r;
        if(l==r) {tree[now].sum=0;return;}
        int m=l+r>>1;
        build(l,m,now<<1),build(m+1,r,now<<1|1);
        tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
    }
    void work(int now,int k)
    {
        tree[now].sum+=(tree[now].r-tree[now].l+1)*k;
        tree[now].lazy+=k;
    }
    void pushdown(int now)
    {
        work(now<<1,tree[now].lazy);
        work(now<<1|1,tree[now].lazy);
        tree[now].lazy=0;
    }
    void modify(int l,int r,int now)
    {
        if(tree[now].l>=l&&tree[now].r<=r) {work(now,1);return;}
        if(tree[now].lazy) pushdown(now);
        int m=tree[now].l+tree[now].r>>1;
        if(m>=l) modify(l,r,now<<1);
        if(m<r) modify(l,r,now<<1|1);
        tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
    }
    int query(int l,int r,int now)
    {
        int ans=0;
        if(tree[now].l>=l&&tree[now].r<=r) {return tree[now].sum;}
        if(tree[now].lazy) pushdown(now);
        int m=tree[now].l+tree[now].r>>1;
        if(m>=l) ans+=query(l,r,now<<1);
        if(m<r) ans+=query(l,r,now<<1|1);
        return ans;
    }
    void update(int x,int y)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            modify(id[top[x]],id[x],1);
            x=f[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        modify(id[x],id[y],1);
    }
    void mo(int l,int r,int now)
    {
        if(tree[now].l>=l&&tree[now].r<=r) {work(now,-1);return;}
        if(tree[now].lazy) pushdown(now);
        int m=tree[now].l+tree[now].r>>1;
        if(m>=l) mo(l,r,now<<1);
        if(m<r) mo(l,r,now<<1|1);
        tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
    }
    int main()
    {
        int n;
        read(n);
        for(re int i=1;i<=n;i++) read(a[i]);
        for(re int i=1,x,y;i<n;i++) read(x),read(y),v[x].pb(y),v[y].pb(x);
        dfs1(rt),dfs2(rt,rt),build(1,n,1);
        for(re int i=2;i<=n;i++) update(a[i-1],a[i]),mo(id[a[i]],id[a[i]],1);
        for(re int i=1;i<=n;i++) printf("%d
    ",query(id[i],id[i],1));
        return 0;
    }
  • 相关阅读:
    DNS 服务器的配置与管理
    为什么苹果不再需要谷歌地图?
    flash安装时提示无法安装解决方法
    苹果新ipad支持siri吗?答案是不支持!
    HTTP的 Basic 验证
    笑解优酷土豆合并
    crontab简介
    循环链表应用
    计算表达式
    走迷宫 dfs
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/11912451.html
Copyright © 2011-2022 走看看