POJ 2828 Buy Tickets(线段树单点)

Posted Ying_zx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2828 Buy Tickets(线段树单点)相关的知识,希望对你有一定的参考价值。

https://vjudge.net/problem/POJ-2828

题目意思:有n个数,进行n次操作,每次操作有两个数pos, ans。pos的意思是把ans放到第pos 位置的后面,pos后面的数就往后推一位。最后输出每个位置的ans。

    思路:根据题 目可知,最后插入的位置的数才是最终不变的数,所以可以从最后的输入作第1个放入,依此类推,倒插入。在插入时也有一定的技术,首先创建一棵空线段树时,每个节点记录当前范围内有多少个空位置。在插入时,要注意,一个数放入之后那么这个位置就不用管了,那么树中所有的空位置就是余下的数所对应的位置,也就是把余下的数又可以看作是一个新的集合。那么每次插入都是当前集合的第1次放。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <string>
 4 #include <sstream>
 5 #include <set>
 6 #include <vector>
 7 #include <stack>
 8 #include <map>
 9 #include <queue>
10 #include <deque>
11 #include <cstdlib>
12 #include <cstdio>
13 #include <cstring>
14 #include <cmath>
15 #include <ctime>
16 #include <functional>
17 // #include <bits/stdc++.h>
18 using namespace std;
19 
20 int n,ans[1000000];
21 
22 struct node
23 {
24     int n,val;
25 }a[1000000];
26 
27 struct tree
28 {
29     int l,r,n;
30 }b[1000000];
31 
32 void init()
33 {
34     int i,j,k;
35     for(k=1;k<n;k<<=1);
36     for(i=k;i<2*k;i++)
37     {
38         b[i].l=b[i].r=i-k+1;
39         b[i].n=1;//每个叶子节点只能放入一个人
40     }
41     for(i=k-1;i>0;i--)
42     {
43         b[i].l=b[2*i].l;
44         b[i].r=b[2*i+1].r;
45         b[i].n=b[2*i].n+b[2*i+1].n;//每个区间是其左右子树所能放入的人数总和
46     }
47 }
48 
49 void insert(int i,int x,int m)
50 {
51     if(b[i].l==b[i].r)//找到叶子节点,这个节点存放该人,并且叶子节点能放入的人数清0
52     {
53         ans[b[i].l]=m;
54         b[i].n=0;
55         return;
56     }
57     if(x<=b[2*i].n)//其插入的位置若能放入左子树(还能放人),往左子树放人,否则走右子树
58         insert(2*i,x,m);
59     else
60         insert(2*i+1,x-b[2*i].n,m);
61         b[i].n--;
62 }
63 
64 int main()
65 {
66     int i,j;
67     while(scanf("%d",&n)!=EOF)
68     {
69         for(i=1;i<=n;i++)
70             scanf("%d%d",&a[i].n,&a[i].val);
71         init();
72         for(i=n;i>0;i--)//逆推
73         {
74             insert(1,a[i].n+1,a[i].val);
75         }
76         cout<<ans[1];
77         for(i=2;i<=n;i++)
78             cout<<" "<<ans[i];
79         cout<<endl;
80     }
81     return 0;
82 }

 

以上是关于POJ 2828 Buy Tickets(线段树单点)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2828Buy Tickets(线段树的单点维护)

POJ 2828 Buy Tickets(线段树单点)

POJ - 2828 Buy Tickets(线段树单点更新)

POJ 2828 Buy Tickets (线段树 or 树状数组+二分)

POJ2828Buy Tickets(线段树)

Buy Tickets POJ - 2828 思维+线段树