PKU 2828 Buy Tickets 线段树想法题 (第4天)

来源:互联网 发布:去掉数组中重复的元素 编辑:程序博客网 时间:2024/06/06 17:08

今天做了两道线段树,还有 昨天的 Bestcoder ,发现线段树真是博大精深,题目的变形也是非常有意思,不想不知道,一想真奇妙。

思路 倒着插,为什么呢?首先最后一个的位置是确定的,倒着放的时候 n-1个是不会对第 n 个产生影响 ,所以放哪就放那了,不会发生变动,那么复杂度就是 O(n)的,怎么用线段树呢?我们思考这样一个问题,对于 i,如果我放第i个,

那么我一定要腾出 i-1个空位 来放 前面的数,所以 线段树的结构 就很明显了 ,用一个变量 记录 这段区间的空余位置

如果剩余的位置 >= i ,也就是放在lson我们 就直接放进去好了,但是如果不够呢,那么我们只能放在rson 的 i-lson的空位出。。。

#include<iostream>#include<cstdio>#define lson id << 1#define rson id << 1|1using namespace std;struct line{    int l,r,len;    int mid(){        return (l + r) / 2;    }}node[1000008];int a[200002],b[200002],tmp[200002];void _Tree(int id ,int l,int r){    node[id].l = l;node[id].r = r,node[id].len = r - l + 1;    if(l == r) return;    int mid = node[id].mid();    _Tree(lson,l,mid);    _Tree(rson,mid+1,r);}void _insert(int id,int k,int n){    node[id].len --;    if(node[id].l == node[id].r )    {        tmp[node[id].l] = b[n];return;    }    if(node[lson].len >=k)_insert(lson,k,n);    else if(node[rson].len >= k-node[lson].len)_insert(rson,k-node[lson].len,n);}int main(){    int n,m;    while(~scanf("%d",&n))    {        _Tree(1,1,n);        for(int i=1;i<=n;i++){            scanf("%d%d",&a[i],&b[i]);a[i]++;        }        for(int i=n;i>=1;i--)            _insert(1,a[i],i);        for(int i=1;i<n;i++)            printf("%d ",tmp[i]);        printf("%d\n",tmp[n]);    }}


0 0
原创粉丝点击