zoukankan      html  css  js  c++  java
  • hdu4217splay

    题意:有1到n的数组,每次删除第k小的值,并求和

    题解:splay基本操作,删除+合并

    坑点:由于不会c++指针操作,sb的只删除了头指针导致一直mle

    #include<bits/stdc++.h>
    #include<ext/rope>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    using namespace __gnu_cxx;
    
    const double g=10.0,eps=1e-7;
    const int N=100000+10,maxn=1000000+10,inf=0x3f3f3f;
    
    struct Node{
        Node* ch[2];
        int v;
        int s;
        int cmp(int x)const{
            int d = x - ch[0]->s;
            if(d==1)return -1;
            return d<=0 ? 0:1;
        }
        void maintain()
        {
            s = 1 + ch[0]->s + ch[1]->s;
        }
    };
    Node* null;
    void Rotate(Node* &o,int d)
    {
        Node* k = o->ch[d^1];
        o->ch[d^1] = k->ch[d];
        k->ch[d] = o;
        o->maintain();k->maintain();
        o = k;
    }
    void splay(Node* &o,int k)
    {
        int d = o->cmp(k);
        if(d==1)k -= o->ch[0]->s + 1;//利用二叉树性质
        if(d!=-1)
        {
            Node* p = o->ch[d];
            int d2 = p->cmp(k);
            int k2 = (d2==0 ? k:k-p->ch[0]->s-1);
            if(d2!=-1)
            {
                splay(p->ch[d2],k2);
                if(d==d2)Rotate(o,d^1);
                else Rotate(o->ch[d],d);
            }
            Rotate(o,d^1);
        }
    }
    Node* Merge(Node* left,Node* right)
    {
        splay(left,left->s);//把排名最大的数splay到根
        left->ch[1] = right;
        left->maintain();
        return left;
    }
    void split(Node* o,int k,Node* &left,Node* &right)
    {
        splay(o,k);//把排名为k的节点splay到根,右侧子树所有节点排名比k大,左侧小
        right = o->ch[1];
        o->ch[1] = null;
        left = o;
        left->maintain();
    }
    Node *root;
    void init(int sz)
    {
        null=new Node;
        null->s=0;
        root=new Node;
        root->v=1;
        root->ch[0]=root->ch[1]=null;
        root->maintain();
        Node* p;
        for(int i=2;i<=sz;i++)
        {
            p=new Node;
            p->v=i;p->s=0;
            p->ch[0]=root,p->ch[1]=null;
            root=p;
            root->maintain();
        }
    }
    void deletetree(Node* &o)
    {
        if(o!=null)
        {
            deletetree(o->ch[0]);
            deletetree(o->ch[1]);
            delete o;
        }
    }
    int main()
    {
        int t,cnt=0;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            init(n+1);
            ll ans=0;
            while(m--)
            {
                int a;
                scanf("%d",&a);
                Node *o,*left,*mid,*right;
                split(root,a,left,o);
                split(o,1,mid,right);
                ans+=mid->v-1;
                root = Merge(Merge(left,right),mid);
            }
            printf("Case %d: %lld
    ",++cnt,ans);
            deletetree(root);
            delete null;
        }
        return 0;
    }
    /************
    
    ************/
    View Code
  • 相关阅读:
    现实世界的Windows Azure:采访Gridsum的Sr.业务发展总监Yun Xu
    现在可用——Windows Azure SDK 1.6
    Rock Paper Azure Challenge回来啦
    这几天比较忙,自己的职业生涯规划好了吗?目标又是什么呢?生活在十字路口。。。。。。
    GDI+ 学习记录(24): 输出文本<3>
    GDI+ 学习记录(30): MetaFile 文件操作
    GDI+ 学习记录(29): 区域 Region
    GDI+ 学习记录(26): 显示图像 Image
    GDI+ 学习记录(25): 变换 Transform
    返回整数的四种情况
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7749915.html
Copyright © 2011-2022 走看看