• POJ 2763 Housewife Wind 树链拋分


    一、前言

      这破题WA了一天,最后重构还是WA,最后通过POJ讨论版得到的数据显示,我看上去是把某个变量写错了。。于是,还是低级错误背锅啊。。。。代码能力有待进一步提升2333333

    二、题意

      某家庭主妇住在一棵树上,他的若干个孩子在树的若干个节点上有分布,主妇同学需要从某给定节点出发,飞到树上的制定节点,在过程中,边权可能会发生改变,问从当前节点到指定节点的边权和。

    三、解法

      树链拋分,点更新查区间。

    // #include<bits/stdc++.h>
    #include<iostream>
    #include<math.h>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    #define ll long long 
    #define pp pair<int ,int>
    
    const ll MAXN=1e5+233;
    
    class Node
    {
        public:
            int next,to,cost;
            void init(int a,int b,int c)
            {
                this->next=a;
                this->to=b;
                this->cost=c;
            }
    };
    Node G[MAXN*3];
    int tree[MAXN],child[MAXN],deep[MAXN],number[MAXN],top[MAXN],points[MAXN],father[MAXN];
    int size,summ,n,q,s;
    void insert(int pos,int key)
    {
        while(pos<MAXN)
        {
            tree[pos]+=key;
            pos+=pos&(-pos);
        }
    }
    int getSum(int pos)
    {
        int ans=0;
        while(pos)
        {
            ans+=tree[pos];
            pos-=pos&(-pos);
        }return ans;
    }
    void add(int from,int to,int cost)
    {
        G[summ].init(points[from],to,cost);
        points[from]=summ++;
    }
    void dfs_1(int now,int last,int dep)
    {
        deep[now]=dep;
        father[now]=last;
        child[now]=1;
        for(int i=points[now];i!=-1;i=G[i].next)
        {
            int tar=G[i].to;
            int cost=G[i].cost;
            if(tar==last)continue;
            dfs_1(tar,now,dep+1);
            child[now]+=child[tar];
        }
    }
    void dfs(int now,int last,int first,int cc=0)
    {
        top[now] = first ? first : now;
        insert(size,cc);
         // cout<<"check_number: "<<now<<ends<<size<<endl;
        number[now]=size++;
        int maxx,pos,coS;
        maxx=pos=-1;
        for(int i=points[now];i!=-1;i=G[i].next)
        {
            int tar=G[i].to;
            int cost=G[i].cost;
            if(tar==last)continue;
            if(maxx<child[tar])
            {
                maxx=child[tar];
                pos=tar;
                coS=cost;
            }
        }if(pos!=-1)dfs(pos,now,top[now],coS);
        for(int i=points[now];i!=-1;i=G[i].next)
        {
            int tar=G[i].to;
            int cost=G[i].cost;
            if(tar==last||tar==pos)continue;
            
            dfs(tar,now,0,cost);
        }
    }
    void update(int num,int key)
    {
        int a=G[num*2].to;
        int b=G[num*2+1].to;
        if(father[a]==b)
        {
            key=key-(getSum(number[a])-getSum(number[a]-1));
            insert(number[a],key);
        }else
        {
            key=key-(getSum(number[b])-getSum(number[b]-1));
            insert(number[b],key);
        }
    }
    int query(int from,int to)
    {
        int ans=0;
        int t1=top[from];
        int t2=top[to];
         // cout<<"check_top: "<<t1<<ends<<t2<<endl;
         // cout<<"check_point: "<<from<<ends<<to<<endl;
        while(t1!=t2)
        {
            if(deep[t1]<deep[t2])
            {
                swap(t1,t2);
                swap(from,to);
            }
            ans+=getSum(number[from])-getSum(number[t1]-1);
            from=father[t1];
            t1=top[from];
        }
        int star=min(number[from],number[to]);
        int endd=max(number[from],number[to]);
         // cout<<ans<<"check_Number: "<<star<<ends<<endd<<endl;
         // cout<<"checkSum: "<<getSum(endd)<<ends<<getSum(star)<<endl;
        ans+=getSum(endd)-getSum(star);
        return ans;
    }
    void init()
    {
        size=1;summ=0;
        memset(points,-1,sizeof(points));
        for(int i=1;i<n;++i)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            // cin>>a>>b>>c;
            add(a,b,c);
            add(b,a,c);
        }dfs_1(1,0,0);
        dfs(1,0,0);
        for(int i=0;i<q;++i)
        {
            int a,b,c;
            // cin>>c;
            scanf("%d",&c);
            if(c)
            {
                // cin>>a>>b;
                scanf("%d%d",&a,&b);
                a--;
                update(a,b);
            }else{
                // cin>>a;
                scanf("%d",&a);
                cout<<query(s,a)<<"
    ";
                s=a;
            }
        }
    }
    
    int main()
    {
        // cin.sync_with_stdio(false);
        cin>>n>>q>>s;init();
        
        return 0;
    }
  • 相关阅读:
    Java中有哪些无锁技术来解决并发问题?如何使用?
    什么是活锁和饥饿?
    如何避免死锁?
    什么是死锁?
    synchronized锁的升级原理是什么?
    Java中的锁之间的区别是什么?
    可重入锁与不可重入锁之间的区别与性能差异?
    数据库分库的策略
    QPS、PV和需要部署机器数量计算公式(转)
    LVS Nginx HAProxy 优缺点
  • 原文地址:https://www.cnblogs.com/rikka/p/7908436.html
Copyright © 2020-2023  润新知