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相关推荐

  1. SPOJ 4487. Can you answer these queries VI splay

    题目链接:点击打开链接 题意比較明显,不赘述. 删除时能够把i-1转到根,把i+1转到根下 则i点就在 根右子树 的左子树,且仅仅有i这一个 点 #include<stdio.h> #in ...

  2. SPOJ GSS2 Can you answer these queries II (线段树离线) - xgtao -

    Can you answer these queries II 这是一道线段树的题目,维护历史版本,给出N(<=100000)个数字(-100000<=x<=100000),要求求出 ...

  3. spoj 2916. Can you answer these queries V(线段树)

    题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出n个数,求区间最大子段和,但是限制了子段的起点终点,起点要在[x1,y1]内,终点要在[x2,y2]内. 思路 ...

  4. [SPOJ] 1043 Can you answer these queries I [GSS1]

    Pro 给你一个序列{A[1], A[2], ..., A[N]}.( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ) 给定"查询"操作的定义如下: Query( ...

  5. SPOJ - GSS3 Can you answer these queries III(线段树+区间合并)

    题目链接:点击查看 题目大意:给出一个长度为n的序列,进行m次操作: 1 x y  查询区间[l,r]中的最大连续子段和 0 x y  将第x个数修改为y 题目分析:因为涉及到单点修改和区间查询等操作 ...

  6. 【线段树】 SPOJ 2713 Can you answer these queries IV

    更新操作:一段区间内的全部数开根号 查询操作:一段区间内的sum值 在一个值更新操作十几次之后会变成 1 之后就不需要再更新这段了 所以在update 某个区间 r-l+1==sum[rt] j就re ...

  7. SPOJ GSS2 Can you answer these queries II

    很好的一道题,想了很久.首先突破的是,可以找到枚举其中一边,假设是尾部y,然后快速找出满足条件的最大的头部x,连续区间的和 很容易想到借助部分和的思想,如果是从y开始往前面累加,那么就是一个关于y的后 ...

  8. SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并

    Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...

  9. 线性代数四之动态DP(广义矩阵加速)——Can you answer these queries III,保卫王国

    动态DP--广义矩阵加速 SP1716 GSS3 - Can you answer these queries III description solution code [NOIP2018 提高组] ...

最新文章

  1. 如何稀释 流事件 (如,onscroll、change、input、mouseover 等 事件)
  2. Spring AOP原理浅析及入门实例
  3. 怎么让PHP网页显示时有表格的效果,html的table用法(让网页的视觉效果显示出来)...
  4. spring boot 集成Mybatis时 Invalid bound statement (not found)
  5. 图像形状特征(二)--Hu距
  6. 【鱼眼镜头7】如何利用鱼眼镜头测距
  7. 小甲鱼Python课后习题028
  8. jquery开发手册(详细全面)
  9. 【自然语言处理】浅谈语料库
  10. foxit pdf editor linux,PDF文件编辑软件—foxit pdf editor
  11. 如何用U盘安装Ubuntu操作系统
  12. IDEA 重复执行 updating indices问题
  13. html创建站点文件夹,构建及访问Web站点
  14. matlab 二值图像黑白颠倒,白天不懂夜的黑,为你开启PS黑白颠倒魔法。
  15. 工作如何避免情绪内耗
  16. 如何实现微信小程序手机号授权
  17. 为什么学python要先学linux-为什么要学习 Linux?
  18. 【TeXstudio】【7】段落,编号与自定义编号——《LaTeX入门》
  19. 数组——洛谷#P1567 统计天数(Python实现)
  20. 乐博乐博亮相2020科博会,掀起少儿编程教育新浪潮!

热门文章

  1. QGIS中如何加载identify
  2. mysql5.7.17免安装版_MySql 5.7.17免安装配置
  3. 大学计算机课感悟100字,停课不停学的心得100字 停课不停学的感想
  4. html 不显示null,如果model.entity为null,则不显示/写特定的html
  5. 非线编辑软件 linux,Flowblade 2.0 发布,非线性开源Linux视频编辑器
  6. mysql join 联合查询,MySQL连接(join)查询
  7. python字典有什么用_什么是python字典??
  8. 服务器上build.xml文件乱码解决(亲测有效)
  9. 【Android】命令行jarsigner签字和解决找不到证书链错误
  10. Opencv3.0.0安装包