zoukankan      html  css  js  c++  java
  • POJ 2828 Buy Tickets

    题意:有n个的排队,每一个人都有一个val来对应,每一个后来人都会插入当前队伍的某一个位置pos。要求把队伍最后的状态输出。

    逆向思维。我们可以这样考虑,最后一个人一定会得到当前队伍他想要的位置,如果我们往前一个阶段,倒数第二个人也一定能得到他想要的位置……,也就是说,我们可以这样处理,我们把最后一个人插入,然后忽略它,再把倒数第二个人插入。即,我们找出当前队伍他想要插入的位置pos的真正坐标就可以。然后去更新整个队伍的长度。如此循环,直到最后一个人。线段树在单点更新的时候,感觉和二分查找是很相似的,可以用它实现。

    // Time 1766ms; Memory 8684K
    #include<iostream>
    #include<cstdio>
    #define maxn 1<<19
    #define mm 200010
    
    using namespace std;
    
    int tmp[mm],d[mm],y[mm];
    int size,n;
    struct line
    {
    	int l,r;
    	int m;
    }a[maxn];
    
    void init()
    {
    	int i;
    	for(n=1;n<size;n<<=1);
    	for(i=n;i<2*n;i++)
    	{
    		a[i].l=a[i].r=i-n+1;
    		if(i-n<size) a[i].m=1;
    		else a[i].m=0;
    	}
    	for(i=n-1;i>0;i--)
    	{
    		a[i].l=a[2*i].l;
    		a[i].r=a[2*i+1].r;
    		a[i].m=a[2*i].m+a[2*i+1].m;
    	}
    }
    void insert(int i,int x,int p)
    {
    	if(a[i].l==a[i].r)
    	{
    		tmp[a[i].l-1]=p;
    		a[i].m=0;
    		return;
    	}
    	if(a[2*i].m>=x) insert(2*i,x,p);
    	else insert(2*i+1,x-a[2*i].m,p);
    	a[i].m--;
    }
    int main()
    {
    	int i;
    	while(scanf("%d",&size)!=EOF)
    	{
    		init();
    		for(i=0;i<size;i++)
    			scanf("%d%d",&d[i],&y[i]);
    		for(i=size-1;i>=0;i--)
    			insert(1,d[i]+1,y[i]);
    		for(i=0;i<size;i++) 
    		{
    			if(i) printf(" ");
    			printf("%d",tmp[i]);
    		}
    		printf("
    ");
    	}
    	return 0;
    }
  • 相关阅读:
    contes配置nginx教程
    jquery 图片放大镜,草稿版
    VUE学习第四次
    VUE学习 第三次
    ryu
    ovs & ryu & mininet
    centos安装mininet 和卸载
    端口镜像
    数据中心网络监控小结
    5、Kafka生产过程分析
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3228758.html
Copyright © 2011-2022 走看看