您的位置:首页 > 其它

hdu 3436

2014-09-09 19:14 176 查看
一开始,直接无脑的对n数组维护。打完之后一看n的范围,默默的删了。

一看范围,就知道要先读进来询问,把涉及到的x做一个统计,这样n的数组

1,2,...,n

(1,x0-1),x0,(x0+1,x1),x1,...,n

这样子就缩好了(一个节点是一个区间)。记录每个节点的起始数。

统计的信息,区间和(即数的个数)。

这样三个操作都能写啦。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>

#define KT ch[ch[root][1]][0]
#define LC ch[x][0]
#define RC ch[x][1]
#define N 310001
using namespace std;

struct node{
char op[10];
int x;
void in(){
scanf("%s%d",op,&x);
}
};
struct SplayTree{
int root;
int fa
;
int ch
[2];
int sz
;
int top1;
int top2;
int ss
;
int que
;

void pushdown(int x){

}
void pushup(int x){
sz[x]=1+sz[LC]+sz[RC];
sum[x]=val[x]+sum[LC]+sum[RC];
}
void rotate(int x,bool f){
int y=fa[x];
int z=fa[y];
pushdown(y);
pushdown(x);
ch[y][!f]=ch[x][f];
fa[ch[x][f]]=y;
fa[x]=z;
if (z) {
ch[z][ch[z][1]==y] = x;
}
ch[x][f] = y;
fa[y]=x;
pushup(y);
}
void splay(int x, int g) {
int y = fa[x];
pushdown(x);
while(y!=g){
int z= fa[y];
bool f = (ch[y][0]==x);
if(z != g && f == (ch[z][0]==y)){
rotate(y,f);
}
rotate(x,f);
y=fa[x];
}
pushup(x);
if(g==0) root = x;
}
void rotateTo(int k,int g) {
int x=root;
pushdown(x);
while(sz[LC] != k){
if(k<sz[LC]){
x=LC;
}else{
k -= sz[LC] + 1;
x = RC;
}
pushdown(x);
}
splay(x,g);
}
void build(int l,int r,int f){
if(l>r){
return ;
}
int x = (l + r) >> 1;
LC = (x - 1 >= l)? (x - 1 + l)>> 1 :0;
RC = (r >= x + 1)? (x + 1 + r)>> 1 :0;
fa[x] = f;
build(l,x - 1,x);
build(x + 1,r,x);
pushup(x);
}
void erase(int x){
if(x==0)
return;
int father= fa[x];
int head = 0, tail=0;
for(que[tail++] =x ; head < tail; head++){
ss[top2++] = que[head];
if(ch[que[head]][0]){
que[tail++]=ch[que[head]][0];
}
if(ch[que[head]][1]){
que[tail++] = ch[que[head]][1];
}
}
ch[father][ch[father][1]==x]=0;
pushup(father);
}
void treaval(int x){
if (x) {
pushdown(x);
treaval(LC);
printf("@%d",val[x]);
//ans[cnt++]=val[x];
treaval(RC);
}
}
void newNode(int &x,int c,int r,int st){
if(top2){
x = ss[--top2];
} else {
x = ++top1;
}
LC = RC = fa[x] =0;
sz[x] = 1;
val[x] = c;
ret[x] = r;
start[x]=st;

if(r&&pos.find(r)==pos.end()){
pos[r]=x;
}

}
void makeTree(int &x, int l, int r, int f){
if(l > r){
return;
}
int m=(l+r)>>1;

newNode(x, num[m], m%2?a[m/2]:0,b[m]);
makeTree(LC,l,m-1,x);
makeTree(RC,m+1,r,x);
fa[x]=f;
pushup(x);
}
void debug(){
treaval(root);
cout<<endl;
}
void cutTo(int l,int r,int c){
rotateTo(l-1,0);
rotateTo(r+1,root);
//debug();
int tmp=KT;
KT=0;
pushup(ch[root][1]);
pushup(root);
rotateTo(c,0);
rotateTo(c+1,root);
fa[tmp]=ch[root][1];
KT=tmp;
pushup(ch[root][1]);
pushup(root);
//debug();
}
int find(int x,int k){
if(sum[LC]<=k-1&&sum[LC]+val[x]>=k){
return start[x]+k-sum[LC]-1;
}
else if(sum[LC]>=k){
return find(LC,k);
}else {
return find(RC,k-sum[LC]-val[x]);
}
}
void init(int n,int m){
pos.clear();
top1=top2=root=0;
newNode(root,0,0,0);
newNode(ch[root][1],0,0,0);
fa[ch[root][1]]=root;
for(int i=0;i<m;i++)
{
Q[i].in();
aa[i]=Q[i].x;
}
sort(aa,aa+m);
a[0]=aa[0];
int cnt=1;
for(int i=1;i<m;i++){
if(aa[i]!=aa[i-1])
a[cnt++]=aa[i];
}
m=cnt;
num[0]=a[0]-1;
b[0]=1;
for(int i=0;i<m;i++){
if(i!=0){
num[i*2]=a[i]-a[i-1]-1;
b[i*2]=a[i-1]+1;
}
num[i*2+1]=1;
b[i*2+1]=a[i];
}
num[m*2]=n-a[m-1];
b[m*2]=a[m-1]+1;
makeTree(KT,0,2*m,ch[root][1]);
pushup(ch[root][1]);
pushup(root);
}
void top(int v){
int x=pos[v];
splay(x,0);
int k=sz[ch[root][0]];

cutTo(k,k,0);
}
int rank(int k){

return find(root,k);
}
int query(int v){
int x=pos[v];
splay(x,0);
//debug();
return sum[LC]+1;
}
void solve(int m){

int v;
for(int i=0;i<m;i++){
// debug();
v=Q[i].x;
if(Q[i].op[0]=='T'){
top(v);
}else if(Q[i].op[0]=='R'){
printf("%d\n",rank(v));
}else{
printf("%d\n",query(v));
}
}
}
int val
;//数值
int sum
;
int ret
;//结果
int start
;//该区间开始的数;

int aa
;
int a
;
int b
;
int num
;
//int pos
;
map<int,int>pos;
node Q
;
}spt;

int main()
{
int T;
cin>>T;
int n,m;
int cas=1;
while(T--){
scanf("%d%d",&n,&m);
printf("Case %d:\n",cas++);
spt.init(n,m);
spt.solve(m);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: