zoukankan      html  css  js  c++  java
  • HYSBZ 1036 【树链剖分】

    思路:

    裸裸的树链剖分....

    树链剖分就是把一棵树分成若干重链和轻链...然后保证形成的线段树上每条链是连续存储的。然后这样就能用线段树进行维护了。

    但是每次一定要保证是在同一条链里边....思路就是这样....

    感觉最近越来越淡定了,题目卡住了也不怎么着急了,慢慢看代码...嗯...有点像学习的感觉了....

    明天青岛理工的邀请赛要好好玩玩...

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int n,m;
    int myw[30100];
    bool vis[30100];
    int siz[30100],dep[30100],top[30100],fa[30100],son[30100],w[30100],fp[30100];
    int totw;
    char typ[20];
    long long INF=0x3f3f3f3f3f;
    struct edge
    {
        int id;
        edge *next;
    };
    edge edges[30100<<1];
    edge *adj[30100];
    struct tr
    {
        int s,e,maxx;
        long long sum;
    };
    tr tree[30100<<2];
    void build(int k,int s,int e)
    {
        tree[k].s=s;
        tree[k].e=e;
        if(s==e)
        {
            tree[k].sum=tree[k].maxx=myw[fp[s]];
            return;
        }
        int mid=(s+e)>>1;
        build(k<<1,s,mid);
        build(k<<1|1,mid+1,e);
        tree[k].maxx=max(tree[k<<1].maxx,tree[k<<1|1].maxx);
        tree[k].sum=tree[k<<1|1].sum+tree[k<<1].sum;
    }
    int ednum;
    inline void AddEdge(int a,int b)
    {
        edge *tmp;
        tmp=&edges[ednum++];
        tmp->id=b;
        tmp->next=adj[a];
        adj[a]=tmp;
    }
    
    void dfs1(int id,int mdep,int f)
    {
        vis[id]=1;
        dep[id]=mdep;
        siz[id]=1;
        fa[id]=f;
        son[id]=0;
        int tmpsiz=-1;
        for(edge *it=adj[id]; it; it=it->next)
        {
            if(!vis[it->id])
            {
                dfs1(it->id,mdep+1,id);
                if(tmpsiz<siz[it->id])
                {
                    tmpsiz=siz[it->id];
                    son[id]=it->id;
                }
                siz[id]+=siz[it->id];
            }
        }
    }
    void dfs2(int id,int ase)
    {
        vis[id]=1;
        top[id]=ase;
        w[id]=++totw;
        fp[totw]=id;
        if(son[id])
            dfs2(son[id],ase);
        for(edge *it=adj[id]; it; it=it->next)
        {
            if(!vis[it->id])
            {
                dfs2(it->id,it->id);
            }
        }
    }
    long long ans;
    void querySum(int k,int s,int e)
    {
        if(tree[k].e==e&&tree[k].s==s)
        {
            ans+=tree[k].sum;
            return;
        }
        int mid=(tree[k].s+tree[k].e)>>1;
        if(e<=mid)
        {
            querySum(k<<1,s,e);
        }
        else if(s>mid)
        {
            querySum(k<<1|1,s,e);
        }
        else
        {
            querySum(k<<1,s,mid);
            querySum(k<<1|1,mid+1,e);
        }
    }
    void qsum(int a,int b)
    {
        int f1=top[a],f2=top[b];
    
        ans=0;
        while(f1!=f2)
        {
            if(dep[f1]<dep[f2])
            {
                swap(f1,f2);
                swap(a,b);
            }
            querySum(1,w[f1],w[a]);
            a=fa[f1];
            f1=top[a];
        }
        if(dep[a]>dep[b])
            swap(a,b);
        querySum(1,w[a],w[b]);
        printf("%lld
    ",ans);
    }
    void queryMax(int k,int s,int e)
    {
        if(tree[k].e==e&&tree[k].s==s)
        {
            ans=max(ans,(long long)tree[k].maxx);
            return;
        }
        int mid=(tree[k].s+tree[k].e)>>1;
        if(e<=mid)
        {
            queryMax(k<<1,s,e);
        }
        else if(s>mid)
        {
            queryMax(k<<1|1,s,e);
        }
        else
        {
            queryMax(k<<1,s,mid);
            queryMax(k<<1|1,mid+1,e);
        }
    }
    void qmax(int a,int b)
    {
        int f1=top[a],f2=top[b];
        ans=INF*(-1);
        while(f1!=f2)
        {
            if(dep[f1]<dep[f2])
            {
                swap(f1,f2);
                swap(a,b);
            }
            queryMax(1,w[f1],w[a]);
            a=fa[f1];
            f1=top[a];
        }
        if(dep[a]>dep[b])
            swap(a,b);
        queryMax(1,w[a],w[b]);
        printf("%lld
    ",ans);
    }
    void update(int k,int pos,int val)
    {
        if(tree[k].s==tree[k].e)
        {
            tree[k].sum=tree[k].maxx=val;
            return;
        }
        int mid=(tree[k].s+tree[k].e)>>1;
        if(pos<=mid)
            update(k<<1,pos,val);
        else
            update(k<<1|1,pos,val);
        tree[k].sum=tree[k<<1|1].sum+tree[k<<1].sum;
        tree[k].maxx=max(tree[k<<1].maxx,tree[k<<1|1].maxx);
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            memset(siz,0,sizeof(siz));
            memset(vis,0,sizeof(vis));
            memset(son,0,sizeof(son));
            fa[1]=0;
            totw=0;
            ednum=0;
            for(int i=1;i<=n;i++)
            {
                adj[i]=NULL;
            }
            for(int i=1; i<n; i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                AddEdge(a,b);
                AddEdge(b,a);
            }
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&myw[i]);
            }
            dfs1(1,1,0);
            memset(vis,0,sizeof(vis));
            dfs2(1,1);
            build(1,1,totw);
            scanf("%d",&m);
            for(int i=1; i<=m; i++)
            {
                int a,b;
                scanf("%s%d%d",typ,&a,&b);
                if(typ[3]=='X')
                {
                    qmax(a,b);
                }
                else if(typ[3]=='M')
                {
                    qsum(a,b);
                }
                else if((typ[3]=='N'))
                {
                    update(1,w[a],b);
                }
            }
        }
    }
    /*
    8
    1 2
    1 4
    2 3
    3 8
    5 6
    7 5
    2 5
    3 7 6 5 8 2 1 0
    1000
    */
  • 相关阅读:
    自定义asp.net mvc Filter 过滤器
    基于委托的C#异步编程的一个小例子 带有回调函数的例子
    ASCII、Unicode和UTF-8编码的区别
    Specification模式的一个不错的示例代码
    codesmith 自动生成C# model 实体模板
    Quartz.NET 实现定时任务调度
    FtpHelper类匿名获取FTP文件
    crc32 根据字符串获取校验值
    机器学习能做什么
    RunHelper,一个为跑步而设计的开源的android app
  • 原文地址:https://www.cnblogs.com/tun117/p/4984861.html
Copyright © 2011-2022 走看看