• LibreOJ #6208. 树上询问


                            内存限制:512 MiB 时间限制:500 ms 标准输入输出
                                题目类型:传统 评测方式:文本比较
                                     上传者: 匿名

    树链剖分+线段树

    屠龙宝刀点击就送

    #include <vector>
    #include <cstdio>
    #define N 100005
    using namespace std;
    vector<int>G[N];
    struct Segment
    {
        int l,r,mid,t,ki,k,flagk,flagt;
        Segment * ch[2];
        Segment ()
        {
            t=ki=k=flagk=flagt=0;
            ch[0]=ch[1]=NULL;
        }
    }*root=new Segment;
    int n,m,tim,top[N],siz[N],dep[N],fa[N],belong[N];
    void dfs1(int x)
    {
        siz[x]=1;
        dep[x]=dep[fa[x]]+1;
        for(int i=0;i<G[x].size();++i)
        {
            int v=G[x][i];
            if(fa[x]==v) continue;
            fa[v]=x;
            dfs1(v);
            siz[x]+=siz[v];
        }
    }
    void dfs2(int x)
    {
        if(!top[x]) top[x]=x;
        int p=0;
        belong[x]=++tim;
        for(int i=0;i<G[x].size();++i)
        {
            int v=G[x][i];
            if(fa[x]!=v&&siz[p]<siz[v]) p=v;
        }
        if(p) top[p]=top[x],dfs2(p);
        for(int i=0;i<G[x].size();++i)
        {
            int v=G[x][i];
            if(fa[x]!=v&&v!=p) dfs2(v);
        }
    }
    void build(Segment *&k,int l,int r)
    {
        k=new Segment;
        k->l=l;k->r=r;
        if(l==r) return;
        k->mid=(l+r)>>1;
        build(k->ch[0],l,k->mid);
        build(k->ch[1],k->mid+1,r);
    }
    void pushdown(Segment *&k)
    {
        k->ch[0]->t+=k->t+k->flagt*k->ch[0]->k;
        k->ch[1]->t+=k->t+k->flagt*k->ch[1]->k;
        k->ch[0]->ki+=k->flagk;
        k->ch[1]->ki+=k->flagk;
        k->ch[0]->flagk+=k->flagk;
        k->ch[1]->flagk+=k->flagk;
        k->ch[0]->flagt+=k->flagt;
        k->ch[1]->flagt+=k->flagt;
        k->flagk=0;
        k->flagt=0;
        k->t=0;
    }
    void plusk(Segment *&k,int l,int r,int d)
    {
        if(k->l==l&&k->r==r) {k->ki+=d;k->k+=d;k->flagk+=d;return;}
        pushdown(k);
        if(l>k->mid) plusk(k->ch[1],l,r,d);
        else if(r<=k->mid) plusk(k->ch[0],l,r,d);
        else plusk(k->ch[0],l,k->mid,d),plusk(k->ch[1],k->mid+1,r,d);
    }
    void plust(Segment *&k,int l,int r,int d)
    {
        if(k->l==l&&k->r==r) {k->t+=d*k->ki;k->flagt+=d;return;}
        pushdown(k);
        if(l>k->mid) plust(k->ch[1],l,r,d);
        else if(r<=k->mid) plust(k->ch[0],l,r,d);
        else plust(k->ch[0],l,k->mid,d),plust(k->ch[1],k->mid+1,r,d);
    }
    int query(Segment *&k,int t)
    {
        if(k->l==k->r) return k->t;
        pushdown(k);
        if(t<=k->mid) return query(k->ch[0],t);
        else return query(k->ch[1],t);
    }
    void solvek(int x,int y,int d)
    {
        for(;top[x]!=top[y];x=fa[top[x]])
        {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            plusk(root,belong[top[x]],belong[x],d);
        }
        if(dep[x]<dep[y]) swap(x,y);
        plusk(root,belong[y],belong[x],d);
    }
    void solvet(int x,int y,int d)
    {
        for(;top[x]!=top[y];x=fa[top[x]])
        {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            plust(root,belong[top[x]],belong[x],d);
        }
        if(dep[x]<dep[y]) swap(x,y);
        plust(root,belong[y],belong[x],d);
    }
    int Main()
    {
        scanf("%d",&n);
        for(int u,v,i=1;i<n;++i)
        {
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);  
        }
        dfs1(1);dfs2(1);
        build(root,1,n);
        scanf("%d",&m);
        for(int opt,x,d;m--;)
        {
            scanf("%d%d",&opt,&x);
            if(opt==1) {scanf("%d",&d);if(d) solvek(1,x,d);} 
            else if(opt==2) {scanf("%d",&d);if(d) solvet(1,x,d);} 
            else printf("%d
    ",query(root,belong[x]));
        }
        return 0;
    }
    int sb=Main();
    int main(int argc,char *argv[]){;}
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    又一种Mysql报错注入
    PHP wget 增强脱裤脚本(PDO MYSQL)
    一种少见的跨目录写webshell方法
    过狗一句话
    在myql sqlserver里边怎么快速找到带有关键字的表
    php读取3389脚本
    学习OpenCV,看这些!
    Git 学习看这篇就够了!
    开发工具使用技巧和插件大总结
    (资源整理)带你入门Spark
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7535870.html
Copyright © 2020-2023  润新知