题意:有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-;
const int N=+,maxn=+,inf=0x3f3f3f; struct Node{
Node* ch[];
int v;
int s;
int cmp(int x)const{
int d = x - ch[]->s;
if(d==)return -;
return d<= ? :;
}
void maintain()
{
s = + ch[]->s + ch[]->s;
}
};
Node* null;
void Rotate(Node* &o,int d)
{
Node* k = o->ch[d^];
o->ch[d^] = 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==)k -= o->ch[]->s + ;//利用二叉树性质
if(d!=-)
{
Node* p = o->ch[d];
int d2 = p->cmp(k);
int k2 = (d2== ? k:k-p->ch[]->s-);
if(d2!=-)
{
splay(p->ch[d2],k2);
if(d==d2)Rotate(o,d^);
else Rotate(o->ch[d],d);
}
Rotate(o,d^);
}
}
Node* Merge(Node* left,Node* right)
{
splay(left,left->s);//把排名最大的数splay到根
left->ch[] = right;
left->maintain();
return left;
}
void split(Node* o,int k,Node* &left,Node* &right)
{
splay(o,k);//把排名为k的节点splay到根,右侧子树所有节点排名比k大,左侧小
right = o->ch[];
o->ch[] = null;
left = o;
left->maintain();
}
Node *root;
void init(int sz)
{
null=new Node;
null->s=;
root=new Node;
root->v=;
root->ch[]=root->ch[]=null;
root->maintain();
Node* p;
for(int i=;i<=sz;i++)
{
p=new Node;
p->v=i;p->s=;
p->ch[]=root,p->ch[]=null;
root=p;
root->maintain();
}
}
void deletetree(Node* &o)
{
if(o!=null)
{
deletetree(o->ch[]);
deletetree(o->ch[]);
delete o;
}
}
int main()
{
int t,cnt=;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
init(n+);
ll ans=;
while(m--)
{
int a;
scanf("%d",&a);
Node *o,*left,*mid,*right;
split(root,a,left,o);
split(o,,mid,right);
ans+=mid->v-;
root = Merge(Merge(left,right),mid);
}
printf("Case %d: %lld\n",++cnt,ans);
deletetree(root);
delete null;
}
return ;
}
/************ ************/

hdu4217splay的更多相关文章

随机推荐

  1. JS+PHP瀑布流效果(二)

    <!-- 加载商品 --><script>    //用户拖动滚动条,达到底部时ajax加载一次数据    var loading = $("#loading&quo ...

  2. CentOS 7.4 防火墙&网卡设置

    防火墙 查看防火墙状态 临时关闭防火墙 (关闭的是当前正在运行的防火墙,重启时还是会自启) 彻底关闭防火墙 (开机不会再自启) 开启防火墙 查看防火墙状态 网卡 查看网卡状态

  3. Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)

    android.util.Log常用的方法有以下5个:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() .根据首字母对应VERBOSE,DEBUG,INFO, WA ...

  4. Java基础—访问权限控制

    Java中访问权限控制的作用: 为了使用户不要触碰那些他们不该触碰的部分,这些部分对于类内部的操作时必要的,但是它并不属于客户端程序员所需接口的一部分. 为了让类库设计者可用更改类的内部工作方式,而不 ...

  5. oracle数据向历史表数据迁移————procedure

    create or replace procedure remove_refund_his_pro isbegin declare cursor refund_query_cur is select ...

  6. input propertychange(1)

    input type=“text” 通过js改变输入框的value值是不会出发input propertychange事件

  7. 获取文件的MD5值,比较两个文件是否完全相同

    代码: public class MD5Test { public static void main(String[] args) { String s1 = MD5Test.MD5Operation ...

  8. shell set 命令

    用set命令可以设置各种shell选项或者列出shell变量.单个选项设置常用的特性.在某些选项之后-o参数将特殊特性打开.在某些选项之后使用+o参数将关闭某些特性,不带任何参数的set命令将显示sh ...

  9. 建议41:使用argparse处理命令行参数

    # -*- coding:utf-8 -*- ''' 以现阶段最好用的参数处理标准库是argparse ''' import argparse parser = argparse.ArgumentPa ...

  10. DNS 介绍

    DNS 介绍 DNS 为 Domain Name System (域名系统的缩写),它是一种将ip地址转换为对应的主机名或将主机名转换成与之对应的ip地址的一种服务机制.DNS使用TCP和UDP,端口 ...