【第22期】观点:IT 行业加班,到底有没有价值?

Poj 2828 Buy Tickets

原创 2015年11月19日 14:55:56

一个线段树加点思维的题目

被窝用splay水过去了Orz

(其实我也不想的,只是正好刚学splay,就看到一个动态插入的题,就。。。就没忍住Orz


用splay写就不用什么思维了,我的思路是给这个队列加上一个虚拟的最后一人来处理刚开始一个人都没有的时候插入的情况

这样写还可以在之后插入的时候无脑插在左边,不用担心没有右边的节点的情况,大概就酱


以及代码如下


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define l ch[0]
#define r ch[1]

struct node{
    int val,siz;
    node * ch[2];
    void maintain(){
        siz = 1;
        if(l) siz+=l->siz;
        if(r) siz+=r->siz;
    }
};

int siz(node * o){
    if(!o)
        return 0;
    return o->siz;
}

const int maxn = 212345;

node nodes[maxn];
int tot;

void out(node * rot,int d,int k){
    if(rot->r)
        out(rot->r,d+1,-1);
    for(int i=0;i<d;i++)
        printf("  ");
    if(k==0)
        printf("--");
    else{
        if(k==-1) printf("/");
        else printf("\\");
    }
    printf("%d ( %d )\n",rot->val,rot->siz);
    if(rot->l)
        out(rot->l,d+1,1);
}

void print(node * root){
    out(root,0,0);
}

node * newnode(int x){
    node * ret = &nodes[tot++];
    ret->val = x;
    ret->siz = 1;
    ret->l=ret->r=NULL;
    return ret;
}

void zg(node* &o,int d){
    node * k = o->ch[d];
    o->ch[d]=k->ch[d^1];
    k->ch[d^1]=o;
    o=k;
    o->maintain();
    o->ch[d^1]->maintain();
}

int splay(node* &rot,int x){
    int p = siz(rot->l)+1;
    if(p==x)
        return 2;
    int d = p > x ? 0 : 1;
    if(d) x-=p;
    int k = splay(rot->ch[d],x);
    if(k==2)
        return d;
    if(k==d) zg(rot,k);
    else zg(rot->ch[d],k);
    zg(rot,d);
    return 2;
}

void fnd(node* &rot,int x){
    int k = splay(rot,x);
    if(k!=2)
        zg(rot,k);
}

void inser(int val,int lo,node* &root){
    node * k = newnode(val);
    lo++;
    if(lo==1){
        fnd(root,1);
        root->l = k;
        root->maintain();
    }
    else{
        fnd(root,lo-1);
        fnd(root,lo);
        root->l->r = k;
        root->l->maintain();
        root->maintain();
    }
}

int ans[maxn];
int len;

void mid(node *rot){
    if(rot->l)
        mid(rot->l);
    ans[len++]=rot->val;
    if(rot->r)
        mid(rot->r);
}


int main(){
    int n;
    while(~scanf("%d",&n)){
        tot = 0;
        node *rot = newnode(0);
        int x,pos;
        for(int i=1;i<=n;i++){
            scanf("%d %d",&pos,&x);
         //   print(rot);
            inser(x,pos,rot);
        }
        len = 0;
        mid(rot);
        for(int i=0;i<n;i++)
            printf(i<n-1?"%d ":"%d\n",ans[i]);
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

【线段树】&nbsp;POJ&nbsp;2828&nbsp;Buy&nbsp;Tickets

D - Buy Tickets Time Limit:4000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit...

POJ-2828-Buy Tickets

POJ-2828-Buy Tickets http://poj.org/problem?id=2828 线段树,逆序插入 </spa

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

poj&nbsp;2828&nbsp;Buy&nbsp;Tickets

Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must ge...

POJ 2828 Buy Tickets

本题使用了一个巧妙的构造方法,首先,如果按顺序插队的话,序列是无法确定的,因为插队的时候被插的人的位置会改变。所以可以倒过来想,最后一个人的位置必然可以确定,然后接着是倒数第二的,依次的位置就都出来了。 然后线段树的功能是统计区间内可插的位置数吧,我们可以先想想叶子节点,如果这个位置被确定了,那么...

POJ 2828 Buy Tickets

http://poj.org/problem?id=2828Buy TicketsTime Limit: 4000MSMemory Limit: 65536KTotal Submissions: 14...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)