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
- hdu4095 Very Boring Homework(笛卡尔树+模拟)
- Boring Homework 二叉搜索树的打印,模拟
- 2011ACM上海邀请赛B题(Boring Homework)----模拟题
- hdu 5324 Boring Class(树状数组+笛卡尔树 | 树状数组+cdq分治)
- UVa 12010 - Boring Homework 解题报告
- 笛卡尔树
- 笛卡尔树
- 笛卡尔树
- 笛卡尔树
- 笛卡尔树
- 笛卡尔树
- 笛卡尔树
- 笛卡尔树
- homework.树
- HDU-4961 Boring Sum STL模拟
- HDU-4961 Boring Sum (模拟)
- 【jzoj5246】【NOIP2017模拟8.8A组】【Trip】【笛卡尔树】【tarjan-lca】
- Boring
- vim基本命令
- VIM 替换\n
- hdu2149 Public Sale
- 点击登陆链接在本页面弹出一个登陆窗口效果
- 使用nfs实现电脑和ARM的共享
- hdu4095 Very Boring Homework(笛卡尔树+模拟)
- 匹配域名正则
- 贪吃蛇游戏
- 嵌入式开发之工具移植---tcpdump移植和使用
- Web服务的体系架构
- vc6.0快捷键
- 内核中各种套接字的关系
- ndk -- 简单入门篇
- 数据库多个事物的并发问题