日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

poj-2828 Buy Tickets ***

發布時間:2024/4/15 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj-2828 Buy Tickets *** 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線段樹

//2828

View Code /*
* [這段話轉的。。]
* 如果我們從頭開始一次做的話,無論是用鏈表還是數組,肯定會超時(鏈表尋址時間長,數組移位時間長。)。
* 所以要用一個快速的方法直接找到位置。但是換個角 度,如果我們反過來排,那樣的話,我們就知道他所在的
* 精確位置!把存儲的結構想象成是鏈表,插隊的人插入后,把他所在的位置從鏈表中屏蔽掉,然后在新的鏈 表種
* 繼續這樣存,這樣的話我們就得到了我們想要的順序!
*
* 按照這種思想,可以用線段樹實現。。。
*
*/

#include
<cstdio>
using namespace std;

const int MAXN = 200000 + 5;
int n, p[MAXN], v[MAXN];
int ans[MAXN], tail;

struct node{
int l, r;
int num, value; //num:當前時刻,該區間有多少空位,, value:該區間的人的value(只葉子節點有意義)
};
node tree[MAXN
* 3]; //注意*3! 否則 RE!!

//建樹
void build(int i, int l, int r){
tree[i].l
= l; tree[i].r = r;
tree[i].num
= r - l + 1; //初始時的空位數

if(l == r) return;
int mid = (l + r) >> 1;
build(i
<<1, l, mid);
build(i
<<1 | 1, mid+1, r);
}

//……
void insert(int i, int p, int v){
tree[i].num
--; //沒到一個區間,該區間的空位數-1,
// 因為既然到達該區間,則該人要么在該區間,要么在該區間的子區間。都導致區間的空位數-1

if(tree[i].l == tree[i].r){ //只葉子節點的value有意義
tree[i].value = v;
return ;
}

if(tree[i<<1].num > p)
insert(i
<<1, p, v);
else
insert(i
<<1 | 1, p-tree[i<<1].num, v); //減去左子區間的空位數
}

void cal(int i){
if(tree[i].l == tree[i].r){
ans[tail
++] = tree[i].value;
return;
}
cal(i
<<1);
cal(i
<<1 | 1);

}

int main(){
while(scanf("%d", &n) == 1){
for(int i=0; i<n; i++)
scanf(
"%d %d", &p[i], &v[i]);

build(
1, 1, n);

for(int i=n-1; i>=0; i--){
insert(
1, p[i], v[i]);
}

tail
= 0;
cal(
1);

printf(
"%d", ans[0]);
for(int i=1; i<n; i++){
printf(
" %d", ans[i]);
}
printf(
"\n");

}

return 0;
}

也可以用樹狀數組

【轉】

View Code /*
PKU 2828:樹狀數組+二分,一開始一直在想如何處理后面加進來的人,即正著考慮的話,當前的信息是不能得到答案的,突然想起以前一道題,發現只要倒著處理的話,就能很好得解決這個問題了,因為最后一個插進來的人所插入的位置就是這個人最后所站的位置。具體的做法就是先在樹狀數組的每個位置上都加1,表示一開始每個位置上都站著一個人,每次二分查找該人所站的位置,找到后把這個位置的1減掉,相當于這個位置被占據了,那么下次要得到相同人數的話位置就相應得往后移了。
*/
#include
<cstdio>
#include
<memory.h>
using namespace std;

const int N = 200005;
int _n;
int res[N];
int c[N];
struct Peo {
int pos, val;
}peo[N];

int lowbit( int n )
{
return n & (-n);
}

void modify( int n, int delta )
{
while( n <= _n )
{
c[n]
+= delta;
n
+= lowbit(n);
}
}

int sum( int n )
{
int ret = 0;
while( n != 0 )
{
ret
+= c[n];
n
-= lowbit(n);
}
return ret;
}

int getRank( int pos ) {
int mid, begin = 1, end = _n;
while ( begin < end ) {
mid
= (begin + end) / 2;
if ( sum(mid) >= pos ) end = mid;
else begin = mid + 1;
}
return end;
}

int main()
{
while ( scanf("%d", &_n) != EOF ) {
int i;
memset(c,
0, sizeof(c));
for (i=1; i<=_n; ++i) {
scanf(
"%d %d", &peo[i].pos, &peo[i].val);
peo[i].pos
++;
modify(i,
1);
}
for (i=_n; i>=1; --i) {
int now = getRank(peo[i].pos);
res[now]
= peo[i].val;
modify(now,
-1);
}
for (i=1; i<_n; ++i) {
if (i == 1) printf("%d", res[i]);
else printf(" %d", res[i]);
}
printf(
" %d\n", res[_n]);
}
return 0;
}

總結

以上是生活随笔為你收集整理的poj-2828 Buy Tickets ***的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。