bzoj2658: [Zjoi2012]小蓝的好友(mrx)
来源:互联网 发布:淘宝买洗衣机可靠吗 编辑:程序博客网 时间:2024/05/01 22:21
突然发现直接做zjoi貌似是不大可能的。。每题都不会啊。。
首先可以看一遍clj的题解,但其中并没有代码实现。据说clj写的是多叉树,但没找到代码,然后又看到了ydc的fhq式treap很短,就模仿他写了。‘
fhq式的treap(可持久化treap)可以参照他本人的博客和他的论文和clj的论文,都有提到这一点。但这题的treap有点不同,首先为每个列都创建一个点,按照中序遍历确定位置,然后每个点都有一个h值,代表多少高度内没有资源点。因为数据时随机生成的所以就能作为treap的随机变量(clj说能用笛卡尔树证明,不明觉厉,懂的人请教教我)。然后对每一行都求出以这行为底边的不含资源点的矩阵的个数。
参考资料:
1、clj详细题解(不让直接链接,用了个短网址) http://hi.baidu.com/wjbzbmr/item/5090883431bd981c9dc65edc
2、ydc大神
/************************************************************** Problem: 2658 User: zhengly123 Language: C++ Result: Accepted Time:1756 ms Memory:16096 kb****************************************************************/ #include <stdlib.h>#include <stdio.h>#include <string.h>#include <iostream>#include <math.h>#include <algorithm>#define MEM(a) memset(a,1,sizeof(a))using namespace std; const int MAXN = 100010;const int MAXNODE = 400010;const int INF = 999999999;typedef pair<int, int> pa;struct node{ int size, h, lch, rch, detla; long long s;}tr[MAXNODE];int root, r, c;inline void up(int c){ tr[c].size = 1 + tr[tr[c].lch].size + tr[tr[c].rch].size; tr[c].s = (long long)tr[tr[c].lch].s + tr[tr[c].rch].s + (((long long)tr[tr[c].lch].h - tr[c].h)*tr[tr[c].lch].size*(tr[tr[c].lch].size + 1) >> 1); tr[c].s += ((long long)tr[tr[c].rch].h - tr[c].h)*tr[tr[c].rch].size*(tr[tr[c].rch].size + 1) >> 1;} inline void down(int c){ if (!tr[c].detla) return; if (tr[c].lch) { tr[tr[c].lch].h += tr[c].detla; tr[tr[c].lch].detla += tr[c].detla; } if (tr[c].rch) { tr[tr[c].rch].h += tr[c].detla; tr[tr[c].rch].detla += tr[c].detla; } tr[c].detla = 0;} pa split(int c, int w){ if (!c) return pa(0, 0); down(c); pa t; if (tr[tr[c].lch].size + 1 <= w) { t = split(tr[c].rch, w - tr[tr[c].lch].size - 1); tr[c].rch = t.first; up(c); return pa(c, t.second); } else { t = split(tr[c].lch, w); tr[c].lch = t.second; up(c); return pa(t.first, c); }} int merge(int t1, int t2){ if (!t1 || !t2) return t1 ? t1 : t2; if (!t1){ up(t2); return t2; } if (!tr){ up(t1); return t1; } down(t1), down(t2); if (tr[t1].h < tr[t2].h) { tr[t1].rch = merge(tr[t1].rch, t2); up(t1); return t1; } else { tr[t2].lch = merge(t1, tr[t2].lch); up(t2); return t2; }} struct point{ int x, y; }p[MAXN]; bool cmp(const point &a, const point &b) { return a.x < b.x; } void work(){ int i, j = 1, n; pa t1, t2; scanf("%d%d%d", &r, &c, &n); long long ans = (long long)r*(r + 1)*c*(c + 1) >> 2; for (i = 1; i <= n; ++i) scanf("%d%d", &p[i].x, &p[i].y); sort(p + 1, p + 1 + n, cmp); for (i = 1; i <= c; ++i) { root = merge(root, i); up(root); } for (i = 1; i <= r; ++i) { tr[root].h += 1; tr[root].detla += 1; if (i == 40000) { i += 0; } while (p[j].x == i) { t1 = split(root, p[j].y - 1); t2 = split(t1.second, 1); tr[t2.first].h = 0; root = merge(t1.first, t2.first); root = merge(root, t2.second); ++j; } ans -= (long long)tr[root].s + (((long long)tr[root].h*tr[root].size*(tr[root].size + 1)) >> 1);//位运算的优先级很坑,一定要加括号 } cout << ans;}int main(){ work(); return 0;}
0 0
- bzoj2658: [Zjoi2012]小蓝的好友(mrx)
- bzoj2658: [Zjoi2012]小蓝的好友(mrx)
- BZOJ2658 [Zjoi2012]小蓝的好友(mrx)
- 【ZJOI2012】小蓝的好友(mrx)
- bzoj 2658: [Zjoi2012]小蓝的好友(mrx) Treap
- BZOJ 2658 [Zjoi2012]小蓝的好友(mrx)
- [bzoj2658]小蓝的好友
- [Treap 笛卡尔树 扫描线 补集转化] BZOJ 2658 [Zjoi2012]小蓝的好友(mrx)
- bzoj 2658: [Zjoi2012]小蓝的好友(mrx) treap+扫描线
- 发现校内网好友买卖的一个小漏洞!并成功实现自动好友买卖!
- 通过QQ小秘书与任意好友聊天的源程序
- 获取QQ所有在线好友IP的小技巧
- 微信好友名字里加入小图标的方法
- 【小白的CFD之旅】03 老蓝
- [BZOJ2657][Zjoi2012]旅游(journey) 树的直径
- [BZOJ 2657][Zjoi2012]旅游(journey):树的直径
- 一个好友的收藏。小洪(洪承煜),不打招呼就转载一下罗,呵呵
- 微信的两个小功能------“摇一摇搜歌”和“雷达加好友”确实打动了我
- FMS安装调试心得
- cocos2d-html5 简易选项卡组件 源码 与实现方法
- python操作redis简单例子
- STL 总结
- python-redis
- bzoj2658: [Zjoi2012]小蓝的好友(mrx)
- NSMUtableDictonary常用用法
- python的redis用法
- 【js设计模式笔记---单体模式】
- Java的访问级别:public(公共),protected(保护),private(私有)
- python&php数据抓取、爬虫分析与中介,有网址案例
- SPID和KPID的区别
- tyvj1114 等差数列
- hdu1026题解