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;
    }
    

      

  • 相关阅读:
    [排序算法] 选择排序(2种)
    [排序算法] 交换排序(2种)
    针对Oracle表 列字段的增加、删除、修改以及重命名操作sql
    myelcipse中SVN进行代码更新和提交
    SVN服务器的搭建
    无法变更启动序列号
    mybatis入门学习记录(一)
    java中判断两个字符串是否相等的问题
    xshell如何同时打开多个标签
    设计模式(六) xml方式实现AOP
  • 原文地址:https://www.cnblogs.com/Przz/p/5812330.html
Copyright © 2011-2022 走看看