zoukankan      html  css  js  c++  java
  • bzoj3083: 遥远的国度

    题意:有棵树,每个点有权值,三种操作,1,修改根,2.把a到b的路径上的点权值修改为c,3,查询以a为子树的最小权值
    题解:毒瘤树链剖分,树链剖分是能处理链和子树的修改查询的,因为树链剖分本质还是dfs序线段树,然后现在问题就变成了换根,假设根为root
    1.root为a,直接查询整棵树,2.lca(root,a)!=a,直接查询a子树,3.lca(root,a)==a,这时a是root的祖先,需要查询的子树是除了a到root路径上的直接儿子的子树的整棵树,分成两段即可,假设直接儿子是x,那么就是(1,l[x]-1),(r[x]+1,n);

    /**************************************************************
        Problem: 3083
        User: walfy
        Language: C++
        Result: Accepted
        Time:6272 ms
        Memory:26228 kb
    ****************************************************************/
     
    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000009
    #define ld long double
    //#define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define ull unsigned long long
    //#define base 1000000000000000000
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
     
    using namespace std;
     
    const ull ba=233;
    const db eps=1e-5;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=100000+10,maxn=1000000+10,inf=0x3f3f3f3f;
     
    ll a[N],mi[N<<2],lazy[N<<2];
    int son[N],dep[N],sz[N],fa[N][20],top[N],id[N],l[N],r[N];
    int head[N],cnt,res;
    struct edge{int to,Next;}e[N<<1];
    void add(int u,int v){e[cnt].to=v,e[cnt].Next=head[u];head[u]=cnt++;}
    void init(){cnt=0;memset(head,-1,sizeof head);memset(son,-1,sizeof son);}
    void dfs1(int u,int f,int de)
    {
        fa[u][0]=f;sz[u]=1;dep[u]=de;
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(x!=f)
            {
                dfs1(x,u,de+1);sz[u]+=sz[x];
                if(son[u]==-1||sz[x]>sz[son[u]])son[u]=x;
            }
        }
    }
    void dfs2(int u,int f,int tp)
    {
        top[u]=tp;l[u]=++res;id[res]=u;
        if(son[u]!=-1)dfs2(son[u],u,tp);
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(x!=f&&x!=son[u])dfs2(x,u,x);
        }
        r[u]=res;
    }
    void pushdown(int rt)
    {
        if(lazy[rt])
        {
            mi[rt<<1]=mi[rt<<1|1]=lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
            lazy[rt]=0;
        }
    }
    void build(int l,int r,int rt)
    {
        if(l==r){mi[rt]=a[id[l]];return ;}
        int m=(l+r)>>1;
        build(ls);build(rs);
        mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);
    }
    void update(int L,int R,ll v,int l,int r,int rt)
    {
        if(L<=l&&r<=R){mi[rt]=lazy[rt]=v;return ;}
        pushdown(rt);
        int m=(l+r)>>1;
        if(L<=m)update(L,R,v,ls);
        if(m<R)update(L,R,v,rs);
        mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);
    }
    void change(int a,int b,ll c)
    {
        int f1=top[a],f2=top[b];
        while(f1!=f2)
        {
            if(dep[f1]<dep[f2])swap(f1,f2),swap(a,b);
            update(l[f1],l[a],c,1,res,1);
            a=fa[f1][0],f1=top[a];
        }
        if(dep[a]>dep[b])swap(a,b);
        update(l[a],l[b],c,1,res,1);
    }
    ll query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)return mi[rt];
        pushdown(rt);
        int m=(l+r)>>1;ll ans=INF;
        if(L<=m)ans=min(ans,query(L,R,ls));
        if(m<R)ans=min(ans,query(L,R,rs));
        return ans;
    }
    int lca(int x,int y)
    {
        if(dep[x]>dep[y])swap(x,y);
        for(int i=19;i>=0;i--)if(((dep[y]-dep[x])>>i)&1)y=fa[y][i];
        if(x==y)return x;
        for(int i=19;i>=0;i--)
            if(fa[x][i]!=fa[y][i])
                x=fa[x][i],y=fa[y][i];
        return fa[x][0];
    }
    int main()
    {
    //    fin;
        int n,m;scanf("%d%d",&n,&m);
        init();
        for(int i=1;i<n;i++)
        {
            int a,b;scanf("%d%d",&a,&b);
            add(a,b);add(b,a);
        }
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        int root;scanf("%d",&root);
        int rr=root;
        dfs1(root,0,1);dfs2(root,0,root);
        build(1,n,1);
        for(int i=1;i<20;i++)for(int j=1;j<=n;j++)fa[j][i]=fa[fa[j][i-1]][i-1];
        while(m--)
        {
            int op,a,b;ll c;scanf("%d",&op);
            if(op==1){scanf("%d",&a),rr=a;}
            else if(op==2){scanf("%d%d%lld",&a,&b,&c);change(a,b,c);}
            else
            {
                scanf("%d",&a);
                if(a==rr)printf("%lld
    ",mi[1]);
                else if(lca(rr,a)!=a)printf("%lld
    ",query(l[a],r[a],1,n,1));
                else
                {
                    int y=rr,x=dep[a]+1;
                    for(int i=19;i>=0;i--)if(((dep[y]-x)>>i)&1)y=fa[y][i];
                    ll ans=INF;
                    if(l[y]>1)ans=min(ans,query(1,l[y]-1,1,n,1));
                    if(r[y]<n)ans=min(ans,query(r[y]+1,n,1,n,1));
                    printf("%lld
    ",ans);
                }
            }
        }
        return 0;
    }
    /********************
    5 2
    4 2
    2 5
    5 3
    3 1
    490 387 927 484 130
    3
    1 2
    3 3
    ********************/
    
  • 相关阅读:
    【SQL】语句/函数汇总
    【SVN】提交报错:×××文件is not under version control
    【AnjularJS系列1】样式相关的指令
    【Javescript】DOM(文档对象模型)
    【HTML】框架集(Framesets)
    【HTML】<!DOCTYPE html>作用
    vue2.0移动端自定义性别选择提示框
    微信小程序踩坑记
    网页里如何使用js禁用F12事件
    网页里如何使用js屏蔽鼠标右击事件
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/10482943.html
Copyright © 2011-2022 走看看