zoukankan      html  css  js  c++  java
  • hdu 3966 树链剖分

    思路:树链剖分入门题,我这门入得好苦啊,程序很快写出来了,可是在LCA过程中把update函数里的左右边界位置写反了,一直RE到死。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<set>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pb push_back
    #define mp make_pair
    #define Maxn 50010
    #define Maxm 200010
    #define LL __int64
    #define Abs(x) ((x)>0?(x):(-x))
    #define lson(x) (x<<1)
    #define rson(x) (x<<1|1)
    #define inf 100000
    #define lowbit(x) (x&(-x))
    #define clr(x,y) memset(x,y,sizeof(x))
    #define Mod 1000000007
    using namespace std;
    int head[Maxn],vi[Maxn],dep[Maxn],w[Maxn],top[Maxn],son[Maxn],sz[Maxn],fa[Maxn],e,id;
    int num[Maxn];
    struct Edge{
        int u,v,next;
    }edge[Maxn*3];
    struct Tree{
        int l,r,c;
        int mid(){
            return (l+r)>>1;
        }
    }tree[Maxn*3];
    void init()
    {
        clr(head,-1);clr(vi,0);
        e=0;id=0;
    }
    void add(int u,int v)
    {
        edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++;
    }
    void BuildTree(int l,int r,int po)
    {
        tree[po].l=l,tree[po].r=r,tree[po].c=0;
        if(l==r)
            return ;
        int mid=tree[po].mid();
        BuildTree(l,mid,lson(po));
        BuildTree(mid+1,r,rson(po));
    }
    void down(int po)
    {
        tree[lson(po)].c+=tree[po].c;
        tree[rson(po)].c+=tree[po].c;
        tree[po].c=0;
    }
    void update(int l,int r,int c,int po)
    {
        if(l<=tree[po].l&&tree[po].r<=r){
            tree[po].c+=c;
            return ;
        }
        down(po);
        int mid=tree[po].mid();
        if(r<=mid)
            update(l,r,c,lson(po));
        else if(l>=mid+1)
            update(l,r,c,rson(po));
        else {
            update(l,mid,c,lson(po));
            update(mid+1,r,c,rson(po));
        }
    }
    int getans(int i,int po)
    {
        if(tree[po].l==tree[po].r){
            return tree[po].c;
        }
        down(po);
        int mid=tree[po].mid();
        if(i<=mid)
            return getans(i,lson(po));
        else
            return getans(i,rson(po));
    }
    void dfs(int u)
    {
        vi[u]=1;
        int i,v;
        son[u]=0,sz[u]=1;
        for(i=head[u];i!=-1;i=edge[i].next){
            v=edge[i].v;
            if(vi[v]) continue;
            dep[v]=dep[u]+1;
            fa[v]=u;
            dfs(v);
            if(sz[v]>sz[son[u]])son[u]=v;
            sz[u]+=sz[v];
        }
    }
    void build(int u,int ti)
    {
        int i,v;
        w[u]=++id;top[u]=ti;vi[u]=1;
        if(son[u]) build(son[u],ti);
        for(i=head[u];i!=-1;i=edge[i].next){
            v=edge[i].v;
            if(vi[v]||v==son[u]) continue;
            build(v,v);
        }
    }
    void calc(int u,int v,int c)
    {
        int f1=top[u],f2=top[v];
        while(f1!=f2){
            if(dep[f1]<dep[f2]){
                swap(f1,f2),swap(u,v);
            }
            update(w[f1],w[u],c,1);
            u=fa[f1];f1=top[u];
        }
        if(dep[u]>dep[v])
            swap(u,v);
        update(w[u],w[v],c,1);
        return ;
    }
    int main()
    {
        int n,m,p,i,j,u,v,val;
        char str[10];
        while(scanf("%d%d%d",&n,&m,&p)!=EOF){
            init();
            for(i=1;i<=n;i++)
                scanf("%d",num+i);
            for(i=1;i<=m;i++){
                scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
            }
            dfs(1);
            clr(vi,0);
            build(1,1);
            BuildTree(1,id,1);
            int ans;
            for(i=1;i<=p;i++){
                scanf("%s",str);
                if(str[0]=='I'){
                    scanf("%d%d%d",&u,&v,&val);
                    calc(u,v,val);
                }
                else if(str[0]=='D'){
                    scanf("%d%d%d",&u,&v,&val);
                    calc(u,v,-val);
                }else {
                    scanf("%d",&u);
                    ans=getans(w[u],1);
                    printf("%d
    ",num[u]+ans);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    共享内存
    用system v消息队列实现回射客户/服务器程序
    消息队列
    在一个递增数组的rotate变换中找target
    栈(Stack)和队列(Queue)是两种操作受限的线性表。
    new与malloc的10点区别(转)
    如何在Ubuntu中安装安全更新
    如何使用Mod_Security和Mod_evasive模块保护Apache 提升DDOS防御力
    如何在Nginx上修复502 Bad Gateway错误
    如何在Ubuntu 20.04上使用Apache和mod_wsgi运行Python脚本?
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3319047.html
Copyright © 2011-2022 走看看