hdu4095 Very Boring Homework(笛卡尔树+模拟)

来源:互联网 发布:演唱会手机字幕软件 编辑:程序博客网 时间:2024/05/21 05:36

题目请戳这里

题目大意:给一个数字序列1-n,按输入次序建一颗BST,然后按照题目描述,输出任意给定矩形的树。给了5条描述,感觉很复杂的样子,然后看这样例自己yy了一下,就那么回事吧。设树高d,n个点,那么这棵树在n*(2d-1)的矩形区域内。n是列,2d-1是行。每个节点只能在一列出现。具体不好描述,还是自己拿笔画画吧。

题目分析:首先要画出这棵树,先要建树。此题的n有100000,如果直接模拟建,最坏复杂度O(n^2),无法忍受。随便画出一颗这样的树,如果给每个点出现的次序标号会发现,这颗树中点出现的次序标号构成了一个小堆。小堆。。。BST。。。。想到了什么?没错,笛卡尔树!

什么是笛卡尔树?

看出这是一颗笛卡尔树,那么就可以O(n)时间建树了。建完树后bfs一遍求出所有点的深度(dfs会爆栈),然后就是模拟了。

trick:1:给的矩形可能爆int。

2:给的矩形可能超出树所在的矩形,那么对于超出的部分,空格照样输出!!!!!!!!(此处PE无数次!!!)(当然前提还是此行有非空白符)


ps:竟然凭一己之力,将此题的ac率怒降10+个百分点!!

pps:太sb了啊啊啊

详情请见代码:

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cctype>using namespace std;const int N = 100005;typedef __int64 ll;struct node{    int l,r,f,key,value;    friend bool operator <(const struct node a,const struct node b)    {        return a.key < b.key;    }}lcm[N];int n,m,root,num,maxdp;int stack[N];int dep[N];int head[N];struct nd{    int to,next;}g[N];void add(int s,int e){    g[num].to = e;    g[num].next = head[s];    head[s] = num ++;}int build(){    int top = -1;    int i,j;    top = -1;    for(i = 1;i <= n;i ++)    {        j = top;        while(j >= 0 && lcm[stack[j]].value > lcm[i].value)            j --;        if(j != -1)        {            lcm[i].f = stack[j];            lcm[stack[j]].r = i;        }        if(j < top)        {            lcm[stack[j + 1]].f = i;            lcm[i].l = stack[j + 1];        }        stack[++ j] = i;        top = j;    }    lcm[stack[0]].f = -1;    return stack[0];}void bfs(int root,int dp){    int front,rear;    front = rear = 0;    dep[root] = dp;    add(dp,root);    stack[rear ++] = root;    while(front != rear)    {        int cur = stack[front ++];        if(lcm[cur].l > 0)        {            dep[lcm[cur].l] = dep[cur] + 1;            add(dep[cur] + 1,lcm[cur].l);            stack[rear ++] = lcm[cur].l;            if(maxdp < dep[cur] + 1)                maxdp = dep[cur] + 1;        }        if(lcm[cur].r > 0)        {            dep[lcm[cur].r] = dep[cur] + 1;            add(dep[cur] + 1,lcm[cur].r);            stack[rear ++] = lcm[cur].r;            if(maxdp < dep[cur] + 1)                maxdp = dep[cur] + 1;        }    }}char ans[205][N + 205];void print(ll l,ll r,ll u,ll d){    ll i,j,k;    for(i = u;i <= d;i ++)    {        memset(ans[i - u],0,sizeof(ans[i - u]));        if(i & 1)        {            for(j = head[(i + 1)>>1];~j;j = g[j].next)            {                ans[i - u][g[j].to] = 'o';                if(lcm[g[j].to].l != -1)                {                    ans[i - u][lcm[g[j].to].l] = '+';                    for(k = lcm[g[j].to].l + 1;k < g[j].to;k ++)                        ans[i - u][k] = '-';                }                if(lcm[g[j].to].r != -1)                {                    ans[i - u][lcm[g[j].to].r] = '+';                    for(k = lcm[g[j].to].r - 1;k > g[j].to;k --)                        ans[i - u][k] = '-';                }            }        }        else        {            for(j = head[i>>1];~j;j = g[j].next)            {                if(lcm[g[j].to].l != -1)                    ans[i - u][lcm[g[j].to].l] = '|';                if(lcm[g[j].to].r != -1)                    ans[i - u][lcm[g[j].to].r] = '|';            }        }    }    for(i = 0;i <= d - u;i ++)    {        bool fuck = false;        for(j = l;j <= r;j ++)            if(ans[i][j])            {                fuck = true;                break;            }        if(fuck == false)            continue;        for(j = l;j <= r;j ++)            if(ans[i][j])                putchar(ans[i][j]);            else                putchar(' ');        putchar(10);    }}void rush(){    ll l,r,u,d;    scanf("%d",&m);    while(m --)    {        scanf("%I64d%I64d%I64d%I64d",&u,&l,&d,&r);        d = u + d - 1;        r = l + r - 1;//        if(r > n)此句是万恶之源!!!!!!!!!!!!//            r = n;        if(d > maxdp + maxdp-1)            d = maxdp + maxdp-1;        print(l,r,u,d);        printf("\n");    }}int main(){    int i,t,cas = 0;    scanf("%d",&t);    while(t --)    {        scanf("%d",&n);        for(i = num = 1;i <= n;i ++)        {            lcm[i].l = lcm[i].r = lcm[i].f = -1;            head[i] = -1;            scanf("%d",&lcm[i].key);            lcm[i].value = i;        }        sort(lcm + 1,lcm + 1 + n);        root = build();        maxdp = 1;        bfs(root,1);        printf("Case #%d:\n",++cas);        rush();    }    return 0;}//812MS14668K