您的位置:首页 > 理论基础 > 数据结构算法

HDU 3727 Jewel 主席树

2016-09-29 13:33 225 查看
最近在学主席树。。。反正感觉挺神奇的。。。

我高中想学,但是并没有看懂。可能是他们写的太屎了

kuangbin的板子也不太行。

poj 2104 那题入门,程序是没错

但是太耦合了,变量也有点意义不明。。。

于是我又去找了找。。。发现应该给一个比利比利的链接

qsc菊苣教你主席树啊

这个讲的不错啊 就是p2的时候码力实在太强。。。只能暂停学姿势

然后我又去找最佳实践,,,

但是感觉都有不舒服的地方。。。只能自己瞎编着上了

【知道最佳实践的一定要告诉我啊

Jewel

题意:初始的链为空,需要支持以下四个操作:略。

题解:Query_1 和 Query_3 很明显就是静态第k小,又因为是权值线段树,Query_2 就是前缀和呗。。。

因为数太大啦,再套个离散化,要离散化首先要把操作离线。ok,这样这题就AC啦

这题昨天晚上从开始读到调完正好一小时,而且中间也跟室友吹吹逼啥的

感觉自己码力很有进步啊!然后交上去WA了。。。

当然我其实知道一个WA点,,,answer 没改成 longlong

满怀信心,再交。。。又WA了。。。

刚刚又xjb交了一遍,还是WA

然后去查题解。。。发现我好像有什么地方理解错了。。。

… and the amounts of “Query_1”, “Query_2” and “Query_3” are all less than 35000.

三种询问的数量都不超过35000。。。我似乎理解成和了????

。。。代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=100001;
const int M=35000*3+N;
struct chair {
int ls,rs,sum;
} T[M*40];
struct oper {
int op,x,y,k;
} op[M];
int root
,A
;
long long ans[4];

int index;
int update(int rt,int l,int r,int x)
{
int newroot=++index;
T[newroot]=T[rt];
T[newroot].sum++;
if (l==r) return newroot;
int m=l+r>>1;
if (x<=m) T[newroot].ls=update(T[newroot].ls,l,m,x);
else T[newroot].rs=update(T[newroot].rs,m+1,r,x);
return newroot;
}

int query(int x,int y,int l,int r,int k)
{
if (l==r) return l;
int m=l+r>>1;
int lsz=T[T[y].ls].sum-T[T[x].ls].sum;
if (lsz>=k) {
return query(T[x].ls,T[y].ls,l,m,k);
} else {
return query(T[x].rs,T[y].rs,m+1,r,k-lsz);
}
}

int getrank(int rt,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return T[rt].sum;
int m=l+r>>1;
int res=0;
if (L<=m) res+=getrank(T[rt].ls,l,m,L,R);
if (m<R) res+=getrank(T[rt].rs,m+1,r,L,R);
return res;
}

void case_init()
{
index=root[0]=0;
T[0].ls=T[0].rs=T[0].sum=0;
memset(ans,0,sizeof(ans));
}

int main()
{
int cas=0;
int q;
while (scanf("%d",&q)!=EOF) {
int n=0;
case_init();
for (int i=1;i<=q;i++) {
char s[10];
scanf("%s",s);
if (s[0]=='I') {
op[i].op=0;
scanf("%d",&op[i].x);
A[++n]=op[i].x;
} else if (s[6]=='1') {
op[i].op=1;
scanf("%d%d%d",&op[i].x,&op[i].y,&op[i].k);
} else if (s[6]=='2') {
op[i].op=2;
scanf("%d",&op[i].x);
} else if (s[6]=='3') {
op[i].op=3;
scanf("%d",&op[i].k);
}
}
sort(A+1,A+1+n);

int tot=0;
for (int i=1;i<=q;i++) {
if (op[i].op==0) {
tot++;
root[tot]=update(root[tot-1],1,n,lower_bound(A+1,A+1+n,op[i].x)-A);
} else {
long long tmp=0;
if (op[i].op==1)
tmp=A[query(root[op[i].x-1],root[op[i].y],1,n,op[i].k)];
if (op[i].op==2)
tmp=getrank(root[tot],1,n,1,lower_bound(A+1,A+1+n,op[i].x)-A);
if (op[i].op==3)
tmp=A[query(root[0],root[tot],1,n,op[i].k)];
ans[op[i].op]+=tmp;
}
}

printf("Case %d:\n",++cas);
for (int i=1;i<4;i++)
printf("%lld\n",ans[i]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 ACM HDOJ