题意:有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; } /************ ************/