zoukankan      html  css  js  c++  java
  • hdu 5398 动态树LCT

    GCD Tree

    Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 415    Accepted Submission(s): 172


    Problem Description
    Teacher Mai has a graph with n vertices numbered from 1 to n. For every edge(u,v), the weight is gcd(u,v). (gcd(u,v) means the greatest common divisor of number uand v).

    You need to find a subset of the edges that forms a tree that includes every vertex, where the total weight of all the edges in the tree is maximized. Print the total weight of these edges.
     
    Input
    There are multiple test cases(about 105).

    For each test case, there is only one line contains one number n(1n105).
     
    Output
    For each test case, print the answer.
     
    Sample Input
    1 2 3 4 5
     
    Sample Output
    0 1 2 4 5
    /*
    hdu 5398 动态树LCT
    
    problem:
    给你n个点,让你构成一棵树,边的权值为端点的最大公约数. 求树的最大边权和
    
    solve:
    枚举所有点,然后贪心的思想.如果n-1个点构成了一个最大的生成树,那么加入第n个点时我们应尽可能把它往
    自己的约数上连(大->小).这样的话就在连接第二个约数的时候就会构成环,所以需要将 当前点-->当前约数点的链上
    断开最小的一条边.
    所以可以枚举 点和其约数,然后利用LCT维护链上面的最小边. 就这个想了很久,不知道应该吧边权保存在哪个端点
    比较好,总感觉会有矛盾 = =||. 结果发现完全可以弄个点来替代边,将点上的值初始化无限大就行了T_T,好2...
    
    hhh-2016-08-21 16:43:04
    */
    #pragma comment(linker,"/STACK:124000000,124000000")
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <map>
    #define lson  ch[0]
    #define rson  ch[1]
    #define ll long long
    #define clr(a,b) memset(a,b,sizeof(a))
    #define key_val ch[ch[root][1]][0]
    using namespace std;
    const int maxn = 100100;
    const int INF = 0x3f3f3f3f;
    
    struct Node* null;
    struct Node
    {
        Node* ch[2] ;
        Node* fa;
        int Min;
        Node* Minnode;
        int Size,lpos,rpos ;
        int rev;
        void newnode(int v)
        {
            Min = v;
            Size = 1 ;
            Minnode = this;
            lpos = rpos = 0;
            fa = ch[0] = ch[1] = null ;
            rev = 0;
        }
        void ini()
        {
            Min = INF;
            Size = 1 ;
            Minnode = this;
            lpos = rpos = 0;
            fa = ch[0] = ch[1] = null ;
            rev = 0;
        }
        void update_rev()
        {
            if(this == null)
                return ;
            swap(ch[0],ch[1]);
            rev ^= 1;
        }
    
        void push_up ()
        {
            Minnode = this;
            if(ch[0] && ch[0]->Minnode->Min < Minnode->Min)
                Minnode = ch[0]->Minnode;
            if(ch[1] && ch[1]->Minnode->Min < Minnode->Min)
                Minnode = ch[1]->Minnode;
        }
    
        void push_down()
        {
            if(rev)
            {
                ch[0]->update_rev();
                ch[1]->update_rev();
                rev = 0;
            }
        }
    
        void link_child ( Node* o , int d )
        {
            ch[d] = o ;
            o->fa = this ;
        }
    
        int isroot()
        {
            return fa == null || this != fa->ch[0] && this != fa->ch[1] ;
        }
        void sign_down ()
        {
            if ( !isroot () ) fa->sign_down () ;
            push_down () ;
        }
        void Rotate ( int d )
        {
            Node* p = fa ;
            Node* gp = fa->fa ;
            p->link_child ( ch[d] , !d ) ;
            if ( !p->isroot () )
            {
                if ( gp->ch[0] == p ) gp->link_child ( this , 0 ) ;
                else gp->link_child ( this , 1 ) ;
            }
            else fa = gp ;
            link_child ( p , d ) ;
            p->push_up () ;
        }
    
        void splay ()
        {
            sign_down () ;
            while ( !isroot () )
            {
                if ( fa->isroot () )
                {
                    this == fa->ch[0] ? Rotate ( 1 ) : Rotate ( 0 ) ;
                }
                else
                {
                    if ( fa == fa->fa->ch[0] )
                    {
                        this == fa->ch[0] ? fa->Rotate ( 1 ) : Rotate ( 0 ) ;
                        Rotate ( 1 ) ;
                    }
                    else
                    {
                        this == fa->ch[1] ? fa->Rotate ( 0 ) : Rotate ( 1 ) ;
                        Rotate ( 0 ) ;
                    }
                }
            }
            push_up () ;
        }
    
        void access()
        {
            Node* o = this ;
            Node* x = null ;
            while ( o != null )
            {
                o->splay () ;
                o->link_child ( x , 1 ) ;
                o->push_up () ;
                x = o ;
                o = o->fa ;
            }
            splay () ;
        }
    
        void make_root()
        {
            access();
            update_rev();
        }
    
        void cut()
        {
            access();
            ch[0]->fa = null;
            ch[0] = null;
            push_up();
        }
        Node* find_root ()
        {
            access () ;
            Node* o = this ;
            while ( o->ch[0] != null )
            {
                o->push_down () ;
                o = o->ch[0] ;
            }
            return o ;
        }
        void cut(Node* to)
        {
            to->make_root();
            cut();
        }
    
        void link(Node* to)
        {
            to->make_root();
            to->fa = this;
        }
        Node* query(Node* to)
        {
            to->make_root();
            access();
            return Minnode;
        }
    };
    Node memory_pool[maxn*2];
    Node* now;
    Node* node[maxn];
    
    void Clear()
    {
        now = memory_pool;
        now->newnode(INF);
        null = now ++;
        null->Size = 0;
    }
    int dp[maxn];
    vector<int > vec[maxn];
    
    void init()
    {
        Clear();
        for(int i = 100000; i >= 1; i--)
        {
            now->newnode(INF);
            node[i] = now++;
            for(int j = i+i; j <= 100000; j+=i)
            {
                vec[j].push_back(i);
            }
        }
        int tans = 0;
        dp[1] = 0;
        now->newnode(INF),node[1] = now++;
        for(int i =2; i <= 100000; i++)
        {
    //        cout << "number:" << i<<endl;
            now->newnode(vec[i][0]);
            Node *tp = now++;
            tp->link(node[i]);
            tp->link(node[vec[i][0]]);
            tp->lpos = i,tp->rpos = vec[i][0];
            tans += vec[i][0];
    //        cout << tp->lpos <<" " <<tp->rpos <<" " <<tans <<endl;
            for(int j = 1;j < vec[i].size();j++)
            {
                int to = vec[i][j];
    //            cout <<"to "<<to <<endl;
    
                Node* tMin = node[to]->query(node[i]);
    //            cout <<"Min:" << tMin->lpos <<" " <<tMin->rpos <<" "<<tMin->Min <<endl;
                if(tMin->Min < to)
                {
                    tans -= tMin->Min;
                    tMin->cut(node[tMin->lpos]);
    //                cout <<"cut1 ";
                    tMin->cut(node[tMin->rpos]);
    //                cout << "cut2" <<endl;
                    tMin->ini();
                    tMin->Min = to,tMin->lpos = i,tMin->rpos = to;
    //                cout << i <<" " <<to<<endl;
    
                    tMin->link(node[i]);
    //                 cout <<"link1 ";
                    tMin->link(node[to]);
    //                cout << "link2" <<endl;
                    tans += to;
                }
            }
            dp[i] = tans ;
        }
    }
    
    
    int main()
    {
    
    //    freopen("in.txt","r",stdin);
        init();
        int n;
        while( scanf("%d",&n) !=EOF)
        {
            printf("%d
    ",dp[n]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    scm工作流部署问题解决
    mysql 数据库时间慢了8小时
    Vue加了二级路由后,跳转后js好像都失效
    flutter 莫名其妙错误集锦
    confluence-6.7.1 install
    git idea 项目复原
    springboot 本地jar发布,打war包
    flutter 初探2--点击按钮打开新窗口
    [转载]无法解决 equal to 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_CI_AS_KS_WS" 之间的排序规则冲突
    [转载]天赋秉异的人永远是少数
  • 原文地址:https://www.cnblogs.com/Przz/p/5812330.html
Copyright © 2011-2022 走看看