您的位置:首页 > 其它

HDU-3727 Jewel(查询第K大是几,以及数字是第几大)

2017-07-19 11:28 375 查看
题意:

插入操作

1查询 S~T 第K是几

2查询 X是当前的第几小

3操作当前第K小是几

思路:

建立主席树 ,三种基本操作

数组开小会TLE。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
struct node
{
int lc,rc,num;
} tree[2000010];
int a[200005],rnu,cnt,now;
int num[200005];
int root[200005];
long long  ans1,ans2,ans3;
struct oper
{
int kind,l,r,k,num;
} choose[200005];

void build(int &i,int l,int r)
{
tree[++cnt]=tree[i];
i=cnt;
if(l==r)
return ;
int mid=(l+r)>>1;
build(tree[i].lc,l,mid);
build(tree[i].rc,mid+1,r);
}
void update(int &i,int l,int r,int num )
{
tree[++cnt]=tree[i];
i=cnt;
tree[i].num++;
if(l==r)
{
return ;
}
int mid=(l+r)>>1;
if(num<=a[mid])
{
update(tree[i].lc,l,mid,num);
}
else
update(tree[i].rc,mid+1,r,num);
}
int query(int i,int j,int l,int r,int k)
{
if(l==r)
return a[l];
int mid=(l+r)>>1;
if(tree[tree[j].lc].num-tree[tree[i].lc].num>=k)
return query(tree[i].lc,tree[j].lc,l,mid,k);
else
return query(tree[i].rc,tree[j].rc,mid+1,r,k-(tree[tree[j].lc].num-tree[tree[i].lc].num));
}
int Query(int i,int l,int r,int num)
{
if(a[r]<=num)
return tree[i].num;
int mid=(l+r)>>1;
if(num<=a[mid])
return Query(tree[i].lc,l,mid,num);
else
return tree[tree[i].lc].num+Query(tree[i].rc,mid+1,r,num);
}

int main()
{
int cs=1,n;
while(scanf("%d",&n)!=EOF)
{
printf("Case %d:\n",cs++);
char op[10];
cnt=now=rnu=0;
for(int i=1; i<=n; i++)
{
scanf("%s",op);
if(op[0]=='I')
{
choose[i].kind=0;
scanf("%d",&choose[i].num);
a[++rnu]=choose[i].num;
}
else
{
if(op
4000
[6]=='1')
{
choose[i].kind=1;
scanf("%d%d%d",&choose[i].l,&choose[i].r,&choose[i].k);
}
else if(op[6]=='2')
{
choose[i].kind=2;
scanf("%d",&choose[i].num);
}
else
{
choose[i].kind=3;
scanf("%d",&choose[i ].k);
}
}
}
sort(a+1,a+1+rnu);
rnu=unique(a+1,a+1+rnu)-a-1;
build(root[0],1,rnu);
ans1=ans2=ans3=0;
for(int i=1;i<=n;i++)
{
if(choose[i].kind==0)
{
now++;
update(root[now]=root[now-1],1,rnu,choose[i].num);
}
else if(choose[i].kind==1)
{
ans1+=query( root[ choose[i].l-1 ],root[ choose[i].r ],1,rnu,choose[i].k );
}
else if(choose[i].kind==2)
{
ans2+=Query(root[now],1,rnu,choose[i].num  );
}
else
{
ans3+=query(root[0],root[now],1,rnu,choose[i].k);
}
}
printf("%lld\n%lld\n%lld\n",ans1,ans2,ans3);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: