码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2828 Buy Tickets | 线段树的喵用

时间:2017-11-20 16:11:13      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:i++   ace   pre   name   str   read   main   can   poj   

题意:

给你n次插队操作,每次两个数,pos,w,意为在pos后插入一个权值为w的数;

最后输出1~n的权值


题解:

首先可以发现,最后一次插入的位置是准确的位置

所以这个就变成了若干个子问题,

所以用线段树维护一下每个区间剩余多少位置可选

对于一个pos

如果左儿子的剩余超过当前位置,就递归进左子树

反之就相当于留出了左儿子剩余的位置,递归进右子树,当前位置变成pos-左儿子剩余位置

请注意是在后面插入

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 typedef long long ll;
 5 #define N 200010
 6 using namespace std;
 7 struct node
 8 {
 9     ll l,r,sum,w;
10 }t[4*N];
11 ll p[N],w[N];
12 ll read()
13 {
14     ll ret=0,neg=1;
15     char j=getchar();
16     for (;j>9 || j<0;j=getchar())
17     if (j==-) neg=-1;
18     for (;j<=9 && j>=0;j=getchar())
19     ret=ret*10+j-0;
20     return ret*neg;
21 }
22 ll n,q,l,r,k,ans[N];
23 void pushup(ll p)
24 {
25     t[p].sum=t[2*p].sum+t[2*p+1].sum;
26 }
27 void build(ll p,ll l,ll r)
28 {
29     t[p].l=l,t[p].r=r;
30     if (l!=r)
31     {
32     ll mid=l+r>>1;
33     build(2*p,l,mid);
34     build(2*p+1,mid+1,r);
35     pushup(p);
36     }
37     else
38     t[p].sum=1;
39 }
40 void modify(ll p,ll pos,ll k)
41 {
42     if (t[p].l==t[p].r)
43     {
44     ans[t[p].l]=k;
45     t[p].sum--;
46     return ;
47     }
48     if (t[2*p].sum>=pos) modify(2*p,pos,k);
49     else modify(2*p+1,pos-t[2*p].sum,k);
50     pushup(p);
51 }
52 int main()
53 {
54     while (scanf("%lld",&n)!=EOF)
55     {
56     build(1,1,n);
57     for (int i=1;i<=n;i++)
58         p[i]=read(),w[i]=read();
59     for (int i=n;i>=1;i--)
60         modify(1,p[i]+1,w[i]);
61     for (int i=1;i<=n;i++)
62         printf("%lld%c",ans[i]," \n"[i==n]);
63     }
64     return 0;
65 }

 

POJ 2828 Buy Tickets | 线段树的喵用

标签:i++   ace   pre   name   str   read   main   can   poj   

原文地址:http://www.cnblogs.com/mrsheep/p/7866681.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!