您的位置:首页 > 其它

poj2828Buy Tickets(线段树 单点更新+区间求和+区间第K值)

2012-09-05 13:24 169 查看
http://poj.org/problem?id=2828

险过 3500+ms

第i个人入队 只影响后面的不会影响前面的 可以倒推 全初始化为1 第i个人去第k位置 由于是倒推,第k个位置为0,表示求k-1位置的时候不能算上k位置的人 根据区间和 求出区间第K值 就是第i个人要放的位置

View Code

#include <iostream>
#include<cstdio>
#include<string.h>
using namespace std;
#define N 200001
int s[N*4],d[N*2][2],po[N*2],j;
void build(int l,int r,int w)
{
if(l==r)
{
s[w] = 1;
return ;
}
int m = (l+r)/2;
build(l,m,2*w);
build(m+1,r,2*w+1);
}
void upset(int l,int r,int w)
{
if(l==r)
return ;
int m  =(l+r)/2;
upset(l,m,2*w);
upset(m+1,r,2*w+1);
s[w] = s[w*2]+s[2*w+1];
}
void add(int p,int da,int l,int r,int w)
{
if(l==r)
{
s[w] = 0;
po[l] = da;
return ;
}
int m= (l+r)/2;
if(p<=s[w*2])
add(p,da,l,m,2*w);
else
add(p-s[w*2],da,m+1,r,2*w+1);
s[w] = s[2*w]+s[w*2+1];
}
int main()
{
int n,i,k,m;
while(scanf("%d",&n)!=EOF)
{
j =0;
memset(po,0,sizeof(po));
for(i = 1; i <= n ; i++)
scanf("%d%d", &d[i][0],&d[i][1]);
build(1,n,1);
upset(1,n,1);
for(i = n ; i >= 1; i--)
add(d[i][0]+1,d[i][1],1,n,1);
for(i = 1 ; i < n ; i++)
printf("%d ",po[i]);
printf("%d\n",po
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐