• Buy Tickets POJ


    Buy Tickets POJ - 2828 思维+线段树

    题意

    是说有n个人买票,但是呢这n个人都会去插队,问最后的队列是什么情况。插队的输入是两个数,第一个是前面有多少人,第二个是这个人的编号,最后输出编号就好了。

    解题思路

    这个题要倒着处理,因为最后一个人插队完成后,别人就不能影响他了。他前面有n个人,那么他就是n+1号位置上,这样来的话,我们只需要知道那个位置,他前面有n个人就行。默认每个位置都没有人。

    详细看代码。

    代码实现

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #define ls (rt<<1)
    #define rs (rt<<1|1)
    #define mid ( (t[rt].l+t[rt].r)>>1 )
    using namespace std;
    const int maxn=2e5+7;
    struct node{
    	int l, r;
    	int sum, val;//sum记录这个区间内有多少空位置,val记录这个人的编号
    }t[maxn<<2];
    struct note{//记录这n个人的插队的顺序
    	int pos, val;
    }a[maxn];
    int n; 
    void up(int rt)
    {
    	t[rt].sum=t[ls].sum+t[rs].sum;
    }
    void build(int rt, int l, int r)
    {
    	t[rt].l=l;
    	t[rt].r=r;
    	t[rt].sum=r-l+1;
    	if(l==r) return ;
    	build(ls, l, mid);
    	build(rs, mid+1, r);
    }
    void update(int rt, int pos, int val)
    {
    	if(t[rt].l==t[rt].r)
    	{
    		t[rt].sum--;
    		t[rt].val=val;
    		return ;
    	}
    	if(t[ls].sum>=pos)
    		update(ls, pos, val);
    	else 
    		update(rs, pos-t[ls].sum, val);
    	up(rt);
    }
    void query(int rt)
    {
    	if(t[rt].l==t[rt].r)
    	{
    		printf("%d ", t[rt].val);
    		return ;
    	}
    	query(ls);
    	query(rs);
    }
    int main() 
    {
    	while(scanf("%d", &n)!=EOF)
    	{
    		for(int i=1; i<=n; i++)
    		{
    			scanf("%d%d", &a[i].pos, &a[i].val);
    		}
    		build(1, 1, n);
    		for(int i=n; i>=1; i--)
    		{
    			update(1, a[i].pos+1, a[i].val);
    		}
    		query(1);
    		printf("
    ");
    	}
    	return 0;
    }
    
    欢迎评论交流!
  • 相关阅读:
    Codeforce 270A
    Codeforce 513A
    Codeforce 834A
    51Nod 1433 0和5
    51Nod 1005 大数加法
    51Nod 1136 欧拉函数
    51Nod 1449 砝码称重 (二进制思想)
    Codeforce 459A
    Codeforce 515A
    Codeforce 474A
  • 原文地址:https://www.cnblogs.com/alking1001/p/11423289.html
Copyright © 2020-2023  润新知