Light OJ 1411 Rip Van Winkle`s Code 线段树成段更新
来源:互联网 发布:世界10大云计算公司 编辑:程序博客网 时间:2024/05/12 23:14
题目来源:Light OJ 1411 Rip Van Winkle`s Code
题意:3中操作 1种查询 求区间和 其中每次可以把一段区间从左到右加上1,2,3,。。。或者从右到左加上。。。3,2,1 或者把某个区间的数都置为v
思路:我是加了6个域
add是这段区间每个数都要加上add add是这么来的 对与123456。。。这个等差数列 可能要分为2个区间 那么我就分成123和123 两个右边的等差数列每个数还应该加上3 所以右区间add加3
v是这个区间都要置为v 他的优先级最高
b是代表这个区间有多少个递增的等差数列
c是代表这个区间有多少个递减的等差数列
sum是区间和
f为真说明要执行C 因为v可以是正和负还可以是0
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 250010;typedef long long LL;struct node{LL sum, add, v, b, c; bool f;}a[maxn<<2];void build(int l, int r, int rt){a[rt].sum = 0;a[rt].add = 0;a[rt].b = 0;a[rt].c = 0;a[rt].f = false;if(l == r)return;int m = (l + r) >> 1;build(l, m, rt<<1);build(m+1, r, rt<<1|1);}void pushdown(int rt, int l, int r){LL k = (LL)(r-l+1);//printf("%d %d %lld\n", l, r, a[rt].v);if(a[rt].f){a[rt<<1].sum = (LL)a[rt].v*(k-(k>>1));a[rt<<1|1].sum = (LL)a[rt].v*(k>>1);a[rt<<1].v = a[rt<<1|1].v = a[rt].v;a[rt<<1].f = a[rt<<1|1].f = true;a[rt].f = false;a[rt<<1].b = a[rt<<1|1].b = 0;a[rt<<1].c = a[rt<<1|1].c = 0;a[rt<<1].add = a[rt<<1|1].add = 0;}LL s1 = (k-(k>>1));LL s2 = (k>>1);if(a[rt].b){a[rt<<1].sum += (LL)a[rt].b*(1+s1)*s1/2;a[rt<<1|1].sum += (LL)a[rt].b*(1+s2)*s2/2+(LL)s2*s1*a[rt].b;a[rt<<1].b += a[rt].b;a[rt<<1|1].b += a[rt].b;a[rt<<1|1].add += (LL)s1*a[rt].b;a[rt].b = 0;}if(a[rt].c){a[rt<<1].sum += (LL)a[rt].c*(1+s1)*s1/2+(LL)s2*s1*a[rt].c;a[rt<<1|1].sum += (LL)a[rt].c*(1+s2)*s2/2;a[rt<<1].c += a[rt].c;a[rt<<1|1].c += a[rt].c;a[rt<<1].add += (LL)s2*a[rt].c;a[rt].c = 0;}if(a[rt].add){a[rt<<1].sum += (LL)a[rt].add*(k-(k>>1));a[rt<<1|1].sum += (LL)a[rt].add*(k>>1);a[rt<<1].add += a[rt].add;a[rt<<1|1].add += a[rt].add; a[rt].add = 0;}}void update(int x, int y, int l, int r, int rt, LL add, LL v, char c){//puts("we");if(l == x && r == y){if(c == 'A'){/*if(a[rt].f){a[rt].sum = (LL)(r-l+1)*v;//a[rt].f = false;}*/a[rt].sum += (LL)(r-l+1)*(r-l+1+1)/2;a[rt].b++;a[rt].sum += (LL)add*(r-l+1);a[rt].add += add;//printf("%d %d %d %lld\n", l, r, a[rt].b, a[rt].sum);}else if(c == 'B'){/*if(a[rt].f){a[rt].sum = (LL)(r-l+1)*v;//a[rt].f = false;}*/a[rt].sum += (LL)(r-l+1)*(r-l+1+1)/2;a[rt].c++;a[rt].sum += (LL)add*(r-l+1);a[rt].add += add;}else if(c == 'C'){a[rt].f = true;a[rt].add = 0;a[rt].sum = (LL)(r-l+1)*v;a[rt].b = 0;a[rt].c = 0;a[rt].v = v;}return;}int m = (l + r) >> 1;pushdown(rt, l, r);if(y <= m){update(x, y, l, m, rt<<1, add, v, c);}else if(x > m){update(x, y, m+1, r, rt<<1|1, add, v, c);}else{if(c == 'A'){update(x, m, l, m, rt<<1, add, v, c);update(m+1, y, m+1, r, rt<<1|1, add+(m-x+1), v, c);}else if(c == 'B'){update(x, m, l, m, rt<<1, add+(y-m), v, c);update(m+1, y, m+1, r, rt<<1|1, add, v, c);}else if(c == 'C'){//puts("as");update(x, m, l, m, rt<<1, add, v, c);update(m+1, y, m+1, r, rt<<1|1, add, v, c);}}a[rt].sum = a[rt<<1].sum + a[rt<<1|1].sum;}LL query(int x, int y, int l, int r, int rt){if(x == l && y == r){//printf("**%d %d %lld\n", l, r, a[rt].sum);return a[rt].sum;}pushdown(rt, l, r);int m = (l + r) >> 1;LL ans = 0;if(y <= m)ans += query(x, y, l, m, rt<<1);else if(x > m)ans += query(x, y, m+1, r, rt<<1|1);elseans = query(x, m, l, m, rt<<1) + query(m+1, y, m+1, r, rt<<1|1);a[rt].sum = a[rt<<1].sum + a[rt<<1|1].sum;return ans;}int main(){int cas = 1;int T;scanf("%d", &T);while(T--){int n = 250000;int q;scanf("%d", &q);printf("Case %d:\n", cas++);build(1, n, 1);while(q--){char s[10];scanf("%s", s);if(s[0] == 'A'){int x, y;scanf("%d %d", &x, &y);update(x, y, 1, n, 1, 0, 0, 'A');}else if(s[0] == 'B'){int x, y;scanf("%d %d", &x, &y);update(x, y, 1, n, 1, 0, 0, 'B');}else if(s[0] == 'C'){int x, y;LL w;scanf("%d %d %lld", &x, &y, &w);update(x, y, 1, n, 1, 0, w, 'C');}else{int x, y;scanf("%d %d", &x, &y);printf("%lld\n", query(x, y, 1, n, 1));}}}return 0;} /*10B 1 4A 1 4S 2 2B 1 3C 1 4 1B 1 4C 3 3 3A 2 3S 2 3B 3 3*/
0 0
- Light OJ 1411 Rip Van Winkle`s Code 线段树成段更新
- Rip Van Winkle's Code
- UVa 12436 Rip Van Winkle's Code 线段树
- Rip Van Winkle's Code - UVa 12436 线段树
- UVA 12436 - Rip Van Winkle's Code(线段树)
- uva 12436 - Rip Van Winkle's Code(线段树)
- UVA 12436 Rip Van Winkle's Code(线段树区间更新)
- Lightoj 1411 - Rip Van Winkle`s Code(线断树)
- UVA 12436 Rip Van Winkle's Code
- UVA 12436 Rip Van Winkle's Code
- 12436 - Rip Van Winkle's Code
- Uva 12436 Rip Van Winkle's Code
- Uva 12436 Rip Van Winkle's Code(区间更新,区间查询)
- uva 12436 Rip Van Winkle's Code 区间更新区间查询
- Light-oj 1080 - Binary Simulation(线段树区间更新)
- light oj 1080 区间更新
- 学院OJ:1684:Light on or off __线段树 区间更新
- Light OJ 1080 - Binary Simulation - (线段树区间更新 单点查询)
- 二叉搜索树删除节点
- Java Eclipse 下载及汉化 及代码自动补全
- C++线程安全的对象生命周期管理
- Android SurfaceView实现游戏2048[三]
- 霹雳火s毕老师_$_Java笔记(一)
- Light OJ 1411 Rip Van Winkle`s Code 线段树成段更新
- Linux下设置ip和主机名进行绑定
- 理解ThreadLocal
- Spark上矩阵运算库(一)—— 矩阵相乘
- 播放器设计与开发 相关目录
- Cocos2dx与安卓混编实现“更换头像”
- 【ASP】ASP vbscript怎么调用ckeditor
- uva 10194(排序、检索)
- UML_时序图画法