CF 702F T-shirt 奇怪的平衡树维护+超强复杂度证明
来源:互联网 发布:软件接口测试视频教程 编辑:程序博客网 时间:2024/06/05 06:52
题目大意
给定
解题思路
一拿到题,我们发现一组一组的询问去做根本无从下手,复杂度根本过不去。那么我们就考虑吧所有询问一起做。
我们把所有的询问扔到一颗平衡树里面,最暴力的思想就是把T-shirt从前往后枚举,我们可以的到可以买这件T-shirt的区间,我们把这个区间的没个数减去
首先可持久化treap合并的复杂度是
我们设后半部分(即没减
即
什么意思?就是说没每次出现b要暴力插入时,减去的
程序
由于这题没打,附上Philipsweng的程序!
#include <cstring>#include <algorithm>#define fe first#define se secondusing namespace std;const int MAXN = 200005;typedef pair<int,int> P;struct Node{ int l,r,cnt,t_c,t_v; int key,val,siz;}T[MAXN];struct Shirt{ int pr,qu; bool operator <(const Shirt &a) const { return qu > a.qu || qu == a.qu && pr < a.pr; }}A[MAXN];int B[MAXN],root,N,M;int Get_Rand(){ return rand() * rand();}void Update(int nt){ T[nt].siz = T[T[nt].l].siz + T[T[nt].r].siz + 1;}void Mark(int nt,int t_c,int t_v){ if (!nt) return; T[nt].cnt += t_c,T[nt].val += t_v; T[nt].t_c += t_c,T[nt].t_v += t_v;}void Down(int nt){ if (!nt) return; Mark(T[nt].l,T[nt].t_c,T[nt].t_v),Mark(T[nt].r,T[nt].t_c,T[nt].t_v); T[nt].t_c = T[nt].t_v = 0;}int Merge(int a,int b){ if (!a || !b) return a ^ b; Down(a),Down(b); if (T[a].key > T[b].key) { T[a].r = Merge(T[a].r,b); Update(a); return a; } T[b].l = Merge(a,T[b].l); Update(b); return b;}P Split(int root,int siz){ if (!siz) return P(0,root); Down(root); if (siz <= T[T[root].l].siz) { P tmp = Split(T[root].l,siz); T[root].l = tmp.se; Update(root); return P(tmp.fe,root); } P tmp = Split(T[root].r,siz - T[T[root].l].siz - 1); T[root].r = tmp.fe; Update(root); return P(root,tmp.se);}int Min(int nt){ for(;T[nt].l;) { Down(nt); nt = T[nt].l; } return nt;}int Max(int nt){ for(;T[nt].r;) { Down(nt); nt = T[nt].r; } return nt;}void MoveL(int &nt){ if (!T[nt].l) { Down(nt); int r = T[nt].r; T[nt].r = 0; Update(nt); nt = r; return; } static int Stk[MAXN]; int top = 0,bak = nt; for(;nt;) Stk[++ top] = nt,Down(nt),nt = T[nt].l; int p = Stk[top]; nt = Stk[top - 1]; if (p) T[nt].l = T[p].r,T[p].r = 0,Update(p),Update(nt); for(;top;top --) Update(Stk[top]); nt = bak;}void Insert(int &root,int nt){ int siz = 0; for(int j = root;j;) { Down(j); if (T[nt].val <= T[j].val) j = T[j].l; else if (T[nt].val > T[j].val) siz += 1 + T[T[j].l].siz,j = T[j].r; } P cur = Split(root,siz); root = Merge(Merge(cur.fe,nt),cur.se);}void Dfs(int root){ if (!root) return; Down(root); Dfs(T[root].l),Dfs(T[root].r);}int main(){ scanf("%d", &N); for(int i = 1;i <= N;i ++) scanf("%d%d", &A[i].pr, &A[i].qu); sort(A + 1,A + N + 1); scanf("%d", &M); for(int i = 1;i <= M;i ++) scanf("%d", &B[i]); for(int i = 1;i <= M;i ++) T[i].key = Get_Rand(),T[i].val = B[i],T[i].siz = 1; for(int i = 1;i <= M;i ++) Insert(root,i); for(int i = 1;i <= N;i ++) { int siz = 0; for(int j = root;j;) { Down(j); if (A[i].pr <= T[j].val) j = T[j].l; else if (A[i].pr > T[j].val) siz += 1 + T[T[j].l].siz,j = T[j].r; } P cur = Split(root,siz); Mark(cur.se,1,-A[i].pr); for(int p,q;(p = Min(cur.se)) && (q = Max(cur.fe)) && T[p].val < T[q].val;) { MoveL(cur.se); Insert(cur.fe,p); } root = Merge(cur.fe,cur.se); } Dfs(root); for(int i = 1;i <= M;i ++) printf("%d%c", T[i].cnt, i == M ? '\n' : ' '); return 0;}
- CF 702F T-shirt 奇怪的平衡树维护+超强复杂度证明
- codeforces 702F T-shirt
- Codeforces 702F T-shirt 可持久化Treap练手
- 收到Topcoder 的T-shirt
- CF#807 B. T-Shirt Hunt(水题)
- Splay复杂度的证明
- 二叉平衡树的算法复杂度笔记
- 红黑树复杂度的数学证明
- 时间复杂度的相关证明
- 【BZOJ3878】【Ahoi2014】奇怪的计算器 维护区间性质。线段树
- T-shirt Fashion
- Design T-Shirt
- Design T-Shirt
- hdu1031 Design T-Shirt
- Design T-Shirt
- Design T-Shirt
- hdu1031Design T-Shirt
- Football T-shirt article626
- 记一道巨简单,但是我没有答上来的Sql面试题
- hdu 5853 Jong Hyok and String
- 【bzoj1208】【HNOI2004】【宠物收养所】【平衡树】【set】
- hdu 1969 Pie 二分
- VS编译Qt源码
- CF 702F T-shirt 奇怪的平衡树维护+超强复杂度证明
- FFmpeg中的滤镜(十二):视频滤镜 -- bwdif
- 为sourceinsight添加makefile、kconfig、*.S文件支持
- OC_类目(Category)、延展(extension)、协议(Protocol)
- AngularJS做SEO
- HDOJ 1874 畅通工程续(最短路)
- 运算符的重载
- JZOJ4681. 选择
- setContentType("text/html;charset=utf-8")、 setCharacterEncoding("utf-8") 和SiteMesh