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
原文地址:https://www.cnblogs.com/acjiumeng/p/7749915.html