poj 2828 Buy Tickets

继续线段树。

这个题的意思是,有很多人,然后后面往前面插队神马的。开始没看懂,没注意下面的HINT = =。。

看discuss说的从后往前建神马的,每次找第pos个空位。可是,肿么转换成线段树呢。

如果线段是空位的话是不行的啊,空位毕竟还是会更新的,但是线段长度是不变的啊。

想了一种方法,很麻烦啊。就是每个节点中存两个值,一个是左子树的空位的个数,一个是右子树空位的个数,然后就相当于类似二分查找了。

如果比左子树的空位的值大那么就去右子树中找,注意,这时候查找的值要变了,变成需要的空位N - 左子树空位的个数。(因为右子树的空位也是从0,1,2。。。开始的)。

交了,G++ TLE,C++2000+MS T T .。。

后搜题解,人家的貌似和我的差不多,但是我的却是看着繁。一个节点存了5个值 = =。。人家的三个就够了。后改了改,只要一个sum,完全可以满足原来的想法。

1700+MS,G++ 3700+MS。。。好弱。。

I 时间少的。。

#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")

using namespace std;

const int MAX = 200010;
struct Tnode{int l,r,sum;};
struct NODE{int pos,val;};
NODE a[MAX];
Tnode node[MAX<<2];
int ind[MAX];
int K;
void init()
{
	memset(node,0,sizeof(node));
}
void Updata_sum(int t)
{
	node[t].sum = node[R(t)].sum + node[L(t)].sum;
}

void Build(int t,int l,int r)
{
	node[t].l = l; node[t].r = r;
	node[t].sum = 0;
	if( l == r - 1 )
	{
		node[t].sum = 1;
		return ;
	}
	int mid = MID(l,r);
	Build(L(t),l,mid);
	Build(R(t),mid,r);
	Updata_sum(t);
}

void Updata(int t,int l)
{
	if( node[t].l == node[t].r - 1 )
	{
		node[t].sum = 0;
		K = node[t].l;
		return ;
	}
	if( l < node[L(t)].sum )
		Updata(L(t),l);
	else
		Updata(R(t),l-node[L(t)].sum);
	Updata_sum(t);
}

int main()
{
	int n;
	int pos,val;
	while( ~scanf("%d",&n) )
	{
		init();
		Build(1,0,n+1);
		for(int i=0; i<n; i++)
			scanf("%d %d",&a[i].pos,&a[i].val);
		
		for(int i=n-1; i>=0; i--)
		{
			Updata(1,a[i].pos);
			ind[K] = a[i].val;
		}
		for(int i=0; i<n-1; i++)
			printf("%d ",ind[i]);
		printf("%d\n",ind[n-1]);
		
	}
return 0;
}


II
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")

using namespace std;

const int MAX = 200010;
struct Tnode{int l,r,ls,rs;};
struct NODE{int pos,val;};
NODE a[MAX];
Tnode node[MAX<<2];
int ind[MAX];
int K;
void init()
{
	memset(node,0,sizeof(node));
}
void Updata_sum(int t)
{
	node[t].ls = node[L(t)].ls + node[L(t)].rs;
	node[t].rs = node[R(t)].ls + node[R(t)].rs;
}

void Build(int t,int l,int r)
{
	node[t].l = l; node[t].r = r;
	node[t].ls = node[t].rs = 0;
	if( l == r - 1 )
	{
		node[t].ls = 0;
		node[t].rs = 1;
		return ;
	}
	int mid = MID(l,r);
	Build(L(t),l,mid);
	Build(R(t),mid,r);
	Updata_sum(t);
}

void Updata(int t,int l,int r)
{
	if( node[t].l == node[t].r - 1 )
	{
		node[t].rs = 0;
		K = node[t].l;
		return ;
	}
	int mid = MID(node[t].l,node[t].r);
	if( l < node[t].ls )
		Updata(L(t),l,r);
	else
		Updata(R(t),l-node[t].ls,r-node[t].ls);
	Updata_sum(t);
}

int main()
{
	int n;
	int pos,val;
	while( ~scanf("%d",&n) )
	{
		init();
		Build(1,0,n+1);
		for(int i=0; i<n; i++)
			scanf("%d %d",&a[i].pos,&a[i].val);
		
		for(int i=n-1; i>=0; i--)
		{
			Updata(1,a[i].pos,a[i].pos+1);
			ind[K] = a[i].val;
		}
		for(int i=0; i<n-1; i++)
			printf("%d ",ind[i]);
		printf("%d\n",ind[n-1]);
		
	}
return 0;
}


你可能感兴趣的:(poj 2828 Buy Tickets)