SPOJ 4487 Can you answer these queries VI
SPOJ_4487
其实这个题目和GSS1是差不多的,只不过由于有增加和删除的操作,这样用线段树就搞不定了,因此可以维护一个splay来实现这些操作。
但是一开始我写出的程序总是TLE,而和网上一些AC的程序对照之后发现无非有两点很不同的地方,一个是他们都用了结构体,另一个是他们都用了指针。在百思不得其解之际,我把以前的若干个数组仿照一个AC的程序写成了结构体,就像下面这样:
struct Splay {int left, right, pre, size, sum, mc, key, lc, rc;#define left(x) sp[x].left#define right(x) sp[x].right#define pre(x) sp[x].pre#define size(x) sp[x].size#define sum(x) sp[x].sum#define mc(x) sp[x].mc#define key(x) sp[x].key#define lc(x) sp[x].lc#define rc(x) sp[x].rc }sp[MAXD];
尼玛……居然AC了……
不知道这是不是也算底层优化……各位TLE了的同仁不妨试试写成结构体……
#include<stdio.h> #include<string.h> #include<cstdlib> #define MAXD 200010 #define INF 0x3f3f3f3f int N, T, a[MAXD], node; struct Splay {int left, right, pre, size, sum, mc, key, lc, rc;#define left(x) sp[x].left#define right(x) sp[x].right#define pre(x) sp[x].pre#define size(x) sp[x].size#define sum(x) sp[x].sum#define mc(x) sp[x].mc#define key(x) sp[x].key#define lc(x) sp[x].lc#define rc(x) sp[x].rc }sp[MAXD]; int Max(int x, int y) {return x > y ? x : y; } void newnode(int &cur, int v) {cur = ++ node;size(cur) = 1;key(cur) = sum(cur) = mc(cur) = lc(cur) = rc(cur) = v;left(cur) = right(cur) = 0; } void update(int cur) {int ls = left(cur), rs = right(cur);size(cur) = size(ls) + size(rs) + 1;sum(cur) = sum(ls) + sum(rs) + key(cur);mc(cur) = Max(rc(ls), 0) + key(cur) + Max(lc(rs), 0);mc(cur) = Max(mc(cur), Max(mc(ls), mc(rs)));lc(cur) = Max(lc(ls), sum(ls) + key(cur) + Max(lc(rs), 0));rc(cur) = Max(rc(rs), sum(rs) + key(cur) + Max(rc(ls), 0)); } void leftrotate(int cur) {int k = right(cur), fa = pre(cur);right(cur) = left(k);pre(right(cur)) = cur;left(k) = cur;pre(cur) = k;pre(k) = fa;right(fa) == cur ? right(fa) = k : left(fa) = k;update(cur); } void rightrotate(int cur) {int k = left(cur), fa = pre(cur);left(cur) = right(k);pre(left(cur)) = cur;right(k) = cur;pre(cur) = k;pre(k) = fa;right(fa) == cur ? right(fa) = k : left(fa) = k;update(cur); } void build(int &cur, int x, int y, int fa) {int mid = (x + y) >> 1;newnode(cur, a[mid]);pre(cur) = fa;if(x == y)return ;if(x < mid)build(left(cur), x, mid - 1, cur);if(mid < y)build(right(cur), mid + 1, y, cur);update(cur); } void splay(int x, int goal) {int y, z;for(;;){if((y = pre(x)) == goal)break;if((z = pre(y)) == goal)right(y) == x ? leftrotate(y) : rightrotate(y);else{if(right(z) == y)right(y) == x ? (leftrotate(z), leftrotate(y)) : (rightrotate(y), leftrotate(z));elseleft(y) == x ? (rightrotate(z), rightrotate(y)) : (leftrotate(y), rightrotate(z));}}if(goal == 0)T = x;update(x); } void rotateto(int k, int goal) {int cur = T, n;for(;;){n = size(left(cur)) + 1;if(n == k)break;if(k < n)cur = left(cur);elsek -= n, cur = right(cur);}splay(cur, goal); } void init() {int i;for(i = 1; i <= N; i ++)scanf("%d", &a[i]);node = size(0) = sum(0) = 0;mc(0) = lc(0) = rc(0) = -INF;newnode(T, 0), newnode(right(T), 0);pre(right(T)) = T;key(T) = key(right(T)) = 0;if(N)build(left(right(T)), 1, N, right(T));update(right(T)), update(T); } void Delete(int x) {rotateto(x, 0), rotateto(x + 2, T);left(right(T)) = 0;update(right(T)), update(T); } void Insert(int x, int y) {rotateto(x, 0), rotateto(x + 1, T);newnode(left(right(T)), y);pre(node) = right(T);update(right(T)), update(T); } void Replace(int x, int y) {rotateto(x + 1, 0);key(T) = y;update(T); } void Query(int x, int y) {rotateto(x, 0), rotateto(y + 2, T);printf("%d\n", mc(left(right(T)))); } void solve() {int i, q, x, y;char op[5];scanf("%d", &q);for(i = 0; i < q; i ++){scanf("%s", op);if(op[0] == 'D'){scanf("%d", &x);Delete(x);}else{scanf("%d%d", &x, &y);if(op[0] == 'I')Insert(x, y);else if(op[0] == 'R')Replace(x, y);elseQuery(x, y);}} } int main() {while(scanf("%d", &N) == 1){init();solve();}return 0; }
转载于:https://www.cnblogs.com/staginner/archive/2012/06/01/2529405.html
SPOJ 4487 Can you answer these queries VI相关推荐
- SPOJ 4487. Can you answer these queries VI splay
题目链接:点击打开链接 题意比較明显,不赘述. 删除时能够把i-1转到根,把i+1转到根下 则i点就在 根右子树 的左子树,且仅仅有i这一个 点 #include<stdio.h> #in ...
- SPOJ GSS2 Can you answer these queries II (线段树离线) - xgtao -
Can you answer these queries II 这是一道线段树的题目,维护历史版本,给出N(<=100000)个数字(-100000<=x<=100000),要求求出 ...
- spoj 2916. Can you answer these queries V(线段树)
题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出n个数,求区间最大子段和,但是限制了子段的起点终点,起点要在[x1,y1]内,终点要在[x2,y2]内. 思路 ...
- [SPOJ] 1043 Can you answer these queries I [GSS1]
Pro 给你一个序列{A[1], A[2], ..., A[N]}.( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ) 给定"查询"操作的定义如下: Query( ...
- SPOJ - GSS3 Can you answer these queries III(线段树+区间合并)
题目链接:点击查看 题目大意:给出一个长度为n的序列,进行m次操作: 1 x y 查询区间[l,r]中的最大连续子段和 0 x y 将第x个数修改为y 题目分析:因为涉及到单点修改和区间查询等操作 ...
- 【线段树】 SPOJ 2713 Can you answer these queries IV
更新操作:一段区间内的全部数开根号 查询操作:一段区间内的sum值 在一个值更新操作十几次之后会变成 1 之后就不需要再更新这段了 所以在update 某个区间 r-l+1==sum[rt] j就re ...
- SPOJ GSS2 Can you answer these queries II
很好的一道题,想了很久.首先突破的是,可以找到枚举其中一边,假设是尾部y,然后快速找出满足条件的最大的头部x,连续区间的和 很容易想到借助部分和的思想,如果是从y开始往前面累加,那么就是一个关于y的后 ...
- SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并
Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...
- 线性代数四之动态DP(广义矩阵加速)——Can you answer these queries III,保卫王国
动态DP--广义矩阵加速 SP1716 GSS3 - Can you answer these queries III description solution code [NOIP2018 提高组] ...
最新文章
- 如何稀释 流事件 (如,onscroll、change、input、mouseover 等 事件)
- Spring AOP原理浅析及入门实例
- 怎么让PHP网页显示时有表格的效果,html的table用法(让网页的视觉效果显示出来)...
- spring boot 集成Mybatis时 Invalid bound statement (not found)
- 图像形状特征(二)--Hu距
- 【鱼眼镜头7】如何利用鱼眼镜头测距
- 小甲鱼Python课后习题028
- jquery开发手册(详细全面)
- 【自然语言处理】浅谈语料库
- foxit pdf editor linux,PDF文件编辑软件—foxit pdf editor
- 如何用U盘安装Ubuntu操作系统
- IDEA 重复执行 updating indices问题
- html创建站点文件夹,构建及访问Web站点
- matlab 二值图像黑白颠倒,白天不懂夜的黑,为你开启PS黑白颠倒魔法。
- 工作如何避免情绪内耗
- 如何实现微信小程序手机号授权
- 为什么学python要先学linux-为什么要学习 Linux?
- 【TeXstudio】【7】段落,编号与自定义编号——《LaTeX入门》
- 数组——洛谷#P1567 统计天数(Python实现)
- 乐博乐博亮相2020科博会,掀起少儿编程教育新浪潮!
热门文章
- QGIS中如何加载identify
- mysql5.7.17免安装版_MySql 5.7.17免安装配置
- 大学计算机课感悟100字,停课不停学的心得100字 停课不停学的感想
- html 不显示null,如果model.entity为null,则不显示/写特定的html
- 非线编辑软件 linux,Flowblade 2.0 发布,非线性开源Linux视频编辑器
- mysql join 联合查询,MySQL连接(join)查询
- python字典有什么用_什么是python字典??
- 服务器上build.xml文件乱码解决(亲测有效)
- 【Android】命令行jarsigner签字和解决找不到证书链错误
- Opencv3.0.0安装包