您的位置:首页 > 其它

HDU 3727 Jewel 简单主席树

2015-04-10 10:56 162 查看
注意题目中的231指的是2^31,然后就是第k小主席树的应用。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=210005;
struct pi{
int lson,rson;
int sum;
}pp[maxn*21];
int root[maxn],tot,cc,x[maxn];
void build(int cnt,int l,int r){
pp[cnt].sum=0;
if(l==r) return ;
pp[cnt].lson=++tot;
build(tot,l,(l+r)/2);
pp[cnt].rson=++tot;
build(tot,(l+r)/2+1,r);
}
void merg(int qq,int cnt,int n,int p,int k){
int le=1,ri=n,mid;
while(le<=ri){
mid=(le+ri)/2;
pp[cnt]=pp[qq];
pp[cnt].sum+=k;
if(le==ri) return ;
if(p<=mid){
pp[cnt].lson=++tot;
cnt=tot;
qq=pp[qq].lson;
ri=mid;
}
else{
pp[cnt].rson=++tot;
cnt=tot;
qq=pp[qq].rson;
le=mid+1;
}
}
}
int query(int cnt,int le,int ri,int l,int r){
if(l>r) return 0;
if(le>=l&&ri<=r) return pp[cnt].sum;
int s=0,mid=(le+ri)/2;
if(l<=mid)
s+=query(pp[cnt].lson,le,mid,l,r);
if(r>mid) s+=query(pp[cnt].rson,mid+1,ri,l,r);
return s;
}
int get(int a,int b,int c){
int le,ri,mid;
le=1;
ri=100000;
while(le<=ri){
mid=(le+ri)/2;
if(query(root[b],1,100000,1,mid)-query(root[a-1],1,100000,1,mid)>=c) ri=mid-1;
else le=mid+1;
}
return le;
}
char c[100];
long long a[5];
struct ppi{
int id;
int a,b,c;
}pp1[maxn];
int main()
{
int i,n,N=0;
while(cin>>n){
cc=0;
tot=0;
root[0]=0;
build(0,1,100000);
printf("Case %d:\n",++N);
for(i=1;i<=3;i++) a[i]=0;
int tt=0;
for(i=0;i<n;i++){
scanf("%s",c);
if(c[0]=='I'){
pp1[i].id=0;
scanf("%d",&pp1[i].a);
x[++tt]=pp1[i].a;
}
else{
if(c[6]=='1'){
pp1[i].id=1;
scanf("%d%d%d",&pp1[i].a,&pp1[i].b,&pp1[i].c);
}
else if(c[6]=='2'){
pp1[i].id=2;
scanf("%d",&pp1[i].a);
}
else{
pp1[i].id=3;
scanf("%d",&pp1[i].a);
}
}
}
sort(x+1,x+tt+1);
for(i=0;i<n;i++){
if(pp1[i].id==0||pp1[i].id==2){
pp1[i].a=lower_bound(x+1,x+tt+1,pp1[i].a)-x;
}
}
for(i=0;i<n;i++){
if(pp1[i].id==0){
cc++;
root[cc]=++tot;
merg(root[cc-1],root[cc],100000,pp1[i].a,1);
}
else{
if(pp1[i].id==1){
a[1]+=x[get(pp1[i].a,pp1[i].b,pp1[i].c)];
}
else if(pp1[i].id==2){
a[2]+=query(root[cc],1,100000,1,pp1[i].a);
}
else{
int le=1,ri=100000,mid;
while(le<=ri){
mid=(le+ri)/2;
if(query(root[cc],1,100000,1,mid)>=pp1[i].a) ri=mid-1;
else le=mid+1;
}
a[3]+=x[le];
}
}
}
for(i=1;i<=3;i++){
printf("%I64d\n",a[i]);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: