线段树(2)

来源:互联网 发布:全职高手周边u盘淘宝网 编辑:程序博客网 时间:2024/05/21 05:43

1、poj2828 Buy Tickets

http://poj.org/problem?id=2828

百度一下,基本上是线段树的解法,但是做过先前树状数组系列题目,我们会发现这道题和SPOJ 227 Ordering the Soldiers http://www.spoj.pl/problems/ORDERS /    (见博客树状数组6)很相似,解法基本一样。从后往前确定人的位置,每确定一个人的位置,我们就把这个人忽略,这样剩下的人的相对位置保持不变,继续确定最后一个人的位置,重复以上过程。明白了这解法基本套用SPOJ 227。奉上树状数组版本(map超时。。。。)

树状数组:

#include <stdio.h>#include <string.h>using namespace std;const int MAX = 200000+10;int n, c[MAX], a[MAX], b[MAX];int mapii[MAX];int lowbit(int x){return x&(-x);}void update(int x, int v){while (x<=n){c[x] += v;x += lowbit(x);}}int getsum(int x){int sum = 0;while (x){sum += c[x];x -= lowbit(x);}return sum;}int find(int x){int l = 1, r = n, mid;while (l < r){mid = (l + r) >> 1;if (getsum(mid) < x){l = mid+1;}else{r = mid;}}return r;}int main(){int i, t;while (scanf("%d", &n) == 1){memset(c, 0, sizeof(c));//mapii.clear();for (i=1; i<=n; i++){update(i, 1);scanf("%d%d", a+i, b+i);}for (i=n; i>=1; i--){t = find(a[i]+1);//printf("%d\n", getsum(a[i]+1));mapii[t] = b[i];update(t, -1);}printf("%d", mapii[1]);for (i=2; i<=n; i++){printf(" %d", mapii[i]);}puts("");}}/*40 771 511 332 69*/


线段树版本:

 

#include <stdio.h>const int MAX =  200000 + 10;int n, map[MAX], c[MAX], b[MAX];struct node{int l;int r;int v;}a[MAX<<2];void pushup(int pos){a[pos].v = a[pos<<1].v + a[pos<<1|1].v;}void build(int l, int r, int pos){a[pos].l = l;a[pos].r = r;if (l == r){a[pos].v = 1;return;}int mid = (l + r) >> 1;build(l, mid, pos<<1);build(mid+1, r, pos<<1|1);pushup(pos);}int query(int goal, int pos){int ans;if (a[pos].l == a[pos].r){a[pos].v-=1;return a[pos].l;}if (a[pos<<1].v>=goal){ans =  query(goal, pos<<1);}else{ans = query(goal-a[pos<<1].v, pos<<1|1);}pushup(pos);return ans;}int main(){int i;      while (scanf("%d", &n) == 1)      {         build(1, n, 1);         for (i=1; i<=n; i++)          {              scanf("%d%d", c+i, b+i);          }          for (i=n; i>=1; i--)          {               map[query(c[i]+1, 1)] = b[i];        }          printf("%d", map[1]);          for (i=2; i<=n; i++)          {              printf(" %d", map[i]);          }          puts("");} }


 

原创粉丝点击