题目链接:http://www.spoj.com/problems/ADALIST/
题意:有3种操作,要求能够在第K个位置加入元素,删除第K个位置的元素,输出第K个位置的元素
分析:这道题可以使用vector或者dequeue暴力跑过,还可以用更省时的Treap来做。复习一下可持久化Treap:
AC代码:
/*************************************************************************
> File Name: test.cpp
> Author: Akira
> Mail: [email protected]
************************************************************************/
#include
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
using namespace std;
#define MaxN 100001
#define MaxM MaxN*10
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
const int mod = 1E9+7;
const double eps = 1e-6;
#define bug cout<<88888888<
#define debug(x) cout << #x" = " << x << endl;
struct Node
{
Node *left, *right;
int val, prio, size;
Node():left(0),right(0){}
}*root,pool[6*MaxN];
inline int size(Node *n){ return n?n->size:0;}
inline void update_size(Node *n){if (n) n->size=1+size(n->left)+size(n->right);}
void merge(Node *&n, Node *a, Node *b)
{
if(!a||!b) n=a?a:b;
else if( a->prio < b->prio)
merge(a->right, a->right, b), n=a;
else
merge(b->left, a, b->left), n=b;
update_size(n);
}
void split(Node *n, Node *&a, Node *&b, int key, int add=0)
{
if(!n) return void(a=b=0);
int cnt = add+ size(n->left) +1;
if(cnt < key)
split(n->right, n->right, b, key, cnt), a=n;
else
split(n->left, a, n->left, key, add), b=n;
update_size(n);
}
void insert(int key, int val)
{
static int ptr = 0;
Node*x = &pool[ptr++];
x->val = val;
x->prio = rand();
Node *a, *b;
split(root, a, b, key);
merge(a,a,x);
merge(root,a,b);
}
void remove(int key)
{
Node *a,*b,*t;
split(root,a,b,key);
split(b,t,b,2);
merge(root,a,b);
}
int find(int key, Node *n=root, int add=0)
{
if(!n) return -1;
int cnt = add + size(n->left) + 1;
if(cnt==key)
return n->val;
else if( cnt < key)
return find(key, n->right, cnt);
else
return find(key, n->left, add);
}
int main()
{
//std::ios::sync_with_stdio(false);
int n,q,a,b,c;
scanf("%d%d", &n, &q);
for(int i=1;i<=n;i++)
{
scanf("%d", &a);
insert(i, a);
}
while(q--)
{
scanf("%d%d", &a, &b);
if(a==1)
{
scanf("%d", &c);
insert(b,c);
}
else if(a==2) remove(b);
else printf("%d\n", find(b));
}
//system("pause");
}