博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 12436 - Rip Van Winkle's Code(线段树)
阅读量:6676 次
发布时间:2019-06-25

本文共 2805 字,大约阅读时间需要 9 分钟。

UVA 12436 - Rip Van Winkle's Code

题意:区间改动一个加入等差数列,一个把区间设为某个值,然后询问区间和

思路:关键在于等差数列的地方,线段树的每一个结点加入一个首项和公差,因为等差数列加上一个等差数列还是一个等差数列。利用这个性质就能够进行维护了,注意set操作会覆盖掉等差数列的操作

代码:

#include 
#include
#define lson(x) ((x<<1)+1)#define rson(x) ((x<<1)+2)typedef long long ll;const int N = 250005;int n;struct Node { ll l, r, a1, d, c, val; int setc;} node[N * 4];void build(ll l, ll r, int x = 0) { node[x].l = l; node[x].r = r; node[x].a1 = node[x].d = node[x].val = node[x].setc = 0; if (l == r) return; ll mid = (l + r) / 2; build(l, mid, lson(x)); build(mid + 1, r, rson(x));}void pushup(int x) { node[x].val = node[lson(x)].val + node[rson(x)].val;}void pushdown(int x) { if (node[x].setc) { node[lson(x)].c = node[rson(x)].c = node[x].c; node[lson(x)].val = (node[lson(x)].r - node[lson(x)].l + 1) * node[x].c; node[rson(x)].val = (node[rson(x)].r - node[rson(x)].l + 1) * node[x].c; node[lson(x)].setc = node[rson(x)].setc = 1; node[lson(x)].a1 = node[lson(x)].d = node[rson(x)].a1 = node[rson(x)].d = 0; node[x].setc = 0; } node[lson(x)].a1 += node[x].a1; node[lson(x)].d += node[x].d; ll l = node[x].l, r = node[x].r; ll mid = (l + r) / 2; ll amid = node[x].a1 + node[x].d * (mid - l + 1); ll len1 = (mid - l + 1), len2 = (r - mid); node[lson(x)].val += node[x].a1 * len1 + len1 * (len1 - 1) / 2 * node[x].d; node[rson(x)].a1 += amid; node[rson(x)].d += node[x].d; node[rson(x)].val += amid * len2 + len2 * (len2 - 1) / 2 * node[x].d; node[x].a1 = node[x].d = 0;}void A(ll l, ll r, ll d, int x = 0) { if (node[x].l >= l && node[x].r <= r) { ll st = node[x].l - l + 1; if (d == -1) st = r - node[x].l + 1; node[x].a1 += st; node[x].d += d; ll len = node[x].r - node[x].l + 1; node[x].val += st * len + len * (len - 1) / 2 * d; return; } pushdown(x); ll mid = (node[x].l + node[x].r) / 2; if (l <= mid) A(l, r, d, lson(x)); if (r > mid) A(l, r, d, rson(x)); pushup(x);}void C(ll l, ll r, ll c, int x = 0) { if (node[x].l >= l && node[x].r <= r) { node[x].setc = 1; node[x].c = c; node[x].val = (node[x].r - node[x].l + 1) * c; node[x].a1 = node[x].d = 0; return; } pushdown(x); ll mid = (node[x].l + node[x].r) / 2; if (l <= mid) C(l, r, c, lson(x)); if (r > mid) C(l, r, c, rson(x)); pushup(x);}ll S(ll l, ll r, int x = 0) { if (node[x].l >= l && node[x].r <= r) return node[x].val; pushdown(x); ll mid = (node[x].l + node[x].r) / 2; ll ans = 0; if (l <= mid) ans += S(l, r, lson(x)); if (r > mid) ans += S(l, r, rson(x)); pushup(x); return ans;}int main() { while (~scanf("%d", &n)) { build(1, 250000); ll a, b, c; char Q[2]; while (n--) { scanf("%s%lld%lld", Q, &a, &b); if (Q[0] == 'C') scanf("%lld", &c); if (Q[0] == 'A') A(a, b, 1); if (Q[0] == 'B') A(a, b, -1); if (Q[0] == 'C') C(a, b, c); if (Q[0] == 'S') printf("%lld\n", S(a, b)); } } return 0;}

转载地址:http://uerxo.baihongyu.com/

你可能感兴趣的文章
android ANR
查看>>
Shell - 简明Shell入门02 - 变量(Variable)
查看>>
Shell - 简明Shell入门06 - 循环语句(Loop)
查看>>
MySQL C#连接ySQL保存当前时间,时分秒都是0,只有日期
查看>>
Aras Innovator DB备份与还原
查看>>
Java设计模式-单例模式
查看>>
git合并多个commit
查看>>
[SCOI2007]修车
查看>>
对数学学习的几点看法
查看>>
陶哲轩实分析 引理 7.1.13 证明
查看>>
纯数学教程 Page 203 例XLI (3)
查看>>
数据库回滚(rollback)和撤销(undo)的区别
查看>>
Treap树
查看>>
正则表达式,re模块
查看>>
测试用例设计-WEB通用测试用例
查看>>
53、listview、expandableListview如何选中时保持高亮?
查看>>
js中将数字和字符串相互转换的方法(转自脚本之家www.jb51.net)
查看>>
centos6.5-VMware虚拟机-双网卡绑定
查看>>
scala言语基础学习二
查看>>
《团队-科学计算器-项目总结》
查看>>