CF 238D Tape Programming
来源:互联网 发布:我想开个网络棋牌室 编辑:程序博客网 时间:2024/06/06 00:38
链表+模拟
VFK题解:应该能注意到这个编程语言有特殊性质即指针的移动是连续的,这意味着假设我们在开头处放置足够多的“>”,那么单独取一个区间出来执行时的程序一定是完整地执行整个代码的程序的一部分。于是我们可以做一个前缀和。f[i][d] 表示第i 个字符在准备第一次访问到的时候数字d 输出了多少次,g[i][d] 表示第i 个字符在指针准备从此处向左移走的时候数字d 输出了多少次。然后查询一段区间时,程序肯定从左端点开始执行,但有可能从左边或者右边出去。于是我们可以比较下左端点的f 和右端点的g 的时间,然后安心地使用前缀和相减得到结果。
说是这么说的,然而代码实现卡了我差不多一个下午。。。用链表模拟要注意如”00000<”的串,在查询[3,6]时是无法得到3处准备左移的时间的,因为在做第3位的时候3已经被删掉了。。。因此为了防止这种情况发生,在orz了汪队的代码之后,我发现更新左移最早时间只需要把它们都压到栈里,等到指针左移时暴力把下标在左移的区间内的栈内元素更新即可。。。(顺便吐槽一下,CF上很多代码时间复杂度是错的(?),只要用”>9>9>9>9>9…<9<9<9<9<9”这种就能卡掉,我该说啥好。。。)
话说这题真有意思呀,tourist考场上都没敲出来呢。。。
#include<cstdio>#include<cstring>#define N 100005#define A 10#define cmin(u,v) (u)>(v)?(u)=(v):0using namespace std;namespace runzhe2000{ const int INF = 1<<29; int ft[N], gt[N], f[N][10], g[N][10], timer = 1, c[10], sta[N], top; char s[N]; bool insta[N]; struct node { int l, r, v; }no[N]; void del(int x) { no[no[x].l].r = no[x].r; no[no[x].r].l = no[x].l; } void main() { int n, q; scanf("%d%d%s",&n,&q,s+1); for(int i = 1, v; i <= n; i++) { if(s[i] >= '0' && s[i] <= '9') v = s[i] - '0'; else v = s[i] == '<' ? 11 : 10; no[i] = (node){i-1, i+1, v}; } memset(ft,63,sizeof(ft)); memset(gt,63,sizeof(gt)); ++timer; ++n; no[n] = (node){n-1,n+1,10}; for(int l = 1; l <= n; l++) if(ft[l] > INF) { for(int cur = l, next, pos = 10; l <= cur && cur <= n; cur = next, ++timer) { if(timer < ft[cur]) { ft[cur] = timer; for(int i = 0; i < A; i++) f[cur][i] = c[i]; } if(no[cur].v < 10) { c[no[cur].v--]++; if(no[cur].v < 0) del(cur); } else { pos = no[cur].v; } next = pos==11?no[cur].l:no[cur].r; if(no[cur].v > 9 && no[next].v > 9) del(cur); if(!insta[cur])sta[++top] = cur, insta[cur] = 1; if(pos == 11) { for(; no[cur].l < sta[top] && sta[top] <= cur && top; --top) { gt[sta[top]] = ++timer; for(int i = 0; i < A; i++) g[sta[top]][i] = c[i]; } } } } for(; q--; ) { int l, r; scanf("%d%d",&l,&r); if(ft[r+1] < gt[l]) { for(int i = 0; i < 10; i++) printf("%d%c",f[r+1][i] - f[l][i],i==9?'\n':' '); } else { for(int i = 0; i < 10; i++) printf("%d%c",g[l][i] - f[l][i],i==9?'\n':' '); } } }}int main(){ runzhe2000::main();}
0 0
- CF 238D Tape Programming
- CF D. Buses
- D. Ball CF
- CF 148D
- CF 173D-- Palindromes
- CF 228D Zigzag
- CF 79D. Password
- CF 214D
- CF 109D
- CF 109D 模拟
- CF 85D
- CF 12D. Ball
- CF 174(div2) D
- CF 161 div2 D
- CF 189 div2 D
- CF 159 div2 d
- CF 313D
- CF 15D Map
- 【Android基础】RecyclerView的设计艺术
- 博为峰Java技术文章 ——JavaSE Swing JPanel II
- truncate 和 delete的区别
- Qt学习笔记-----QListWidget,QTableWidget和QTreeWidget
- 实践SEH攻击和虚函数攻击
- CF 238D Tape Programming
- android studio 在 真机调试 时device offline waiting for debugger
- OpenCV实现RGB颜色空间和HSI颜色空间的相互转换
- Android控件绑定代码快速生成工具
- 让微信小程序在浏览器和自己的App中运行--自己写的一个开源框架FreeMina(开发中。。)
- 【转载】Spark and SPARQL:RDF Graphs and GraphX
- 负责任有担当三星电子联合第三方客观公正公布Galaxy Note7燃损原因
- ORBSLAM2在Ubuntu14.04上详细配置流程
- 走近三星全球发布会 为确保未来产品安全做了哪些措施?