Codeforces Round #254 (Div. 1)C. DZY Loves Colors(线段树经典操作/分块)
来源:互联网 发布:张居正 知乎 编辑:程序博客网 时间:2024/05/26 12:56
C. DZY Loves Colors
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
DZY loves colors, and he enjoys painting.
On a colorful day, DZY gets a colorful ribbon, which consists of n units (they are numbered from 1 to n from left to right). The color of the i-th unit of the ribbon is i at first. It is colorful enough, but we still consider that the colorfulness of each unit is 0 at first.
DZY loves painting, we know. He takes up a paintbrush with color x and uses it to draw a line on the ribbon. In such a case some contiguous units are painted. Imagine that the color of unit i currently is y. When it is painted by this paintbrush, the color of the unit becomes x, and the colorfulness of the unit increases by |x - y|.
DZY wants to perform m operations, each operation can be one of the following:
Paint all the units with numbers between l and r (both inclusive) with color x.Ask the sum of colorfulness of the units between l and r (both inclusive).
Can you help DZY?
Input
The first line contains two space-separated integers n, m (1 ≤ n, m ≤ 105).
Each of the next m lines begins with a integer type (1 ≤ type ≤ 2), which represents the type of this operation.
If type = 1, there will be 3 more integers l, r, x (1 ≤ l ≤ r ≤ n; 1 ≤ x ≤ 108) in this line, describing an operation 1.
If type = 2, there will be 2 more integers l, r (1 ≤ l ≤ r ≤ n) in this line, describing an operation 2.
Output
For each operation 2, print a line containing the answer — sum of colorfulness.
Examples
Input
3 3
1 1 2 4
1 2 3 5
2 1 3
Output
8
Input
3 4
1 1 3 4
2 1 1
2 2 2
2 3 3
Output
3
2
1
Input
10 6
1 1 5 3
1 2 7 9
1 10 10 11
1 3 8 12
1 1 10 3
2 1 10
Output
129
Note
In the first sample, the color of each unit is initially [1, 2, 3], and the colorfulness is [0, 0, 0].
After the first operation, colors become [4, 4, 3], colorfulness become [3, 2, 0].
After the second operation, colors become [4, 5, 5], colorfulness become [3, 3, 2].
So the answer to the only operation of type 2 is 8.
题意 : 一开始,a[i]=i,b[i]=0
然后两个操作
1.使得[l,r]的b[i]+=fabs(x-a[i]),a[i]=x
2.查询[l,r]的b[i]和
解法1:线段树 打same标记,有限次之后区间缩成一个点,这是套路。
//358ms 11500kb#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 1e5+7;namespace segmenttree{ #define lson l,m,o*2 #define rson m+1,r,o*2+1 LL sum[maxn*4], same[maxn<<2], add[maxn<<2]; void pushup(int o){ if(same[o*2] == same[o*2+1]) same[o] = same[o*2]; else same[o] = 0; sum[o] = sum[o*2] + sum[o*2+1]; } void pushdown(int o, int len){ if(same[o]){ sum[o*2] += add[o] * (len - (len>>1)); sum[o*2+1] += add[o] * (len >> 1); add[o*2] += add[o]; add[o*2+1] += add[o]; add[o] = 0; same[o*2] = same[o*2+1] = same[o]; } } void build(int l, int r, int o){ if(l == r){ same[o] = l; return ; } int m = (l + r) / 2; build(lson); build(rson); pushup(o); } void update(int L, int R, int c, int l, int r, int o){ if(L <= l && r <= R){ if(same[o]){//只有区间颜色相同才更新 add[o] += abs(c - same[o]); sum[o] += abs(c - same[o]) * (r - l + 1); same[o] = c; return ; } } pushdown(o, r - l + 1); int m = (l + r) / 2; if(R <= m) update(L, R, c, lson); else if(L > m) update(L, R, c, rson); else{ update(L, m, c, lson); update(m + 1, R, c, rson); } pushup(o); } LL query(int L, int R, int l, int r, int o){ if(L <= l && r <= R){ return sum[o]; } pushdown(o, r - l + 1); int m = (l + r) / 2; if(R <= m) return query(L, R, lson); else if(L > m) return query(L, R, rson); else return query(L, m, lson) + query(m + 1, R, rson); }}using namespace segmenttree;int main(){ int n, m; scanf("%d%d", &n, &m); build(1, n, 1); for(int i = 1; i <= m; i++){ int cmd; scanf("%d", &cmd); if(cmd == 1){ int l, r, x; scanf("%d%d%d", &l, &r, &x); update(l, r, x, 1, n, 1); } else{ int l, r; scanf("%d%d", &l, &r); printf("%lld\n", query(l, r, 1, n, 1)); } } return 0;}
解法2:分块,维护lazy和lazyb
#include <bits/stdc++.h>using namespace std;const int maxn = 1e6+100;typedef long long LL;int n, m, num, block, belong[maxn], l[maxn], r[maxn];LL a[maxn], b[maxn], lazy[maxn], sum[maxn],lazyb[maxn];void build(){ block = sqrt(n); num = n / block; if(n%block) num++; for(int i = 1; i <= num; i++){ l[i] = (i - 1) * block + 1, r[i] = i * block, lazy[i] = -1, sum[i] = 0, lazyb[i] = 0; } r[num] = n; for(int i = 1; i <= n; i++) belong[i] = (i - 1) / block + 1;}void update(int L, int R, int v){ if(belong[L] == belong[R]){ //同一块暴力更新 if(lazy[belong[L]] != -1){ for(int i = l[belong[L]]; i <= r[belong[L]]; i++) a[i] = lazy[belong[L]]; lazy[belong[L]] = -1; } for(int i = L; i <= R; i++){ b[i] += abs(a[i] - v); sum[belong[L]] += abs(a[i] - v); a[i] = v; } } else{ //开头的那不完整的一块 if(lazy[belong[L]] != -1){ for(int i = l[belong[L]]; i <= r[belong[L]]; i++) a[i] = lazy[belong[L]]; lazy[belong[L]] = -1; } for(int i = L; i <= r[belong[L]]; i++){ b[i] += abs(v - a[i]); sum[belong[L]] += abs(v - a[i]); a[i] = v; } //中间最多sqrt(n)块 for(int i = belong[L] + 1; i < belong[R]; i++){ if(lazy[i] != -1){ lazyb[i] += abs(lazy[i] - v); sum[i] += abs(lazy[i] - v) * (r[i] - l[i] + 1); lazy[i] = v; } else{ for(int j = l[i]; j <= r[i]; j++){ b[j] += abs(v - a[j]); sum[i] += abs(v - a[j]); a[j] = v; } lazy[i] = v; } } //末尾一块,不超过sqrt(n) if(lazy[belong[R]] != -1){ for(int i = l[belong[R]]; i <= r[belong[R]]; i++) a[i] = lazy[belong[R]]; lazy[belong[R]] = -1; } for(int i = l[belong[R]]; i <= R; i++){ b[i] += abs(a[i] - v); sum[belong[R]] += abs(a[i] - v); a[i] = v; } }}LL query(int L, int R){ LL ans = 0; if(belong[L] == belong[R]){ for(int i = L; i <= R; i++) ans += b[i] + lazyb[belong[i]]; } else{ for(int i = L; i <= r[belong[L]]; i++) ans += b[i] + lazyb[belong[L]]; for(int i = belong[L] + 1; i < belong[R]; i++) ans += sum[i]; for(int i = l[belong[R]]; i <= R; i++) ans += b[i] + lazyb[belong[R]]; } return ans;}int main(){ scanf("%d%d", &n, &m); build(); for(int i = 1; i <= n; i++) a[i] = i, b[i] = 0; while(m--){ int cmd; scanf("%d", &cmd); if(cmd == 1){ int a, b; LL v; scanf("%d%d%lld", &a, &b, &v); update(a, b, v); } else{ int a, b; scanf("%d%d", &a, &b); printf("%lld\n", query(a, b)); } } return 0;}
- Codeforces Round #254 (Div. 1)C. DZY Loves Colors(线段树经典操作/分块)
- Codeforces Round #254 (Div. 1)C. DZY Loves Colors(线段树经典操作/分块)
- Codeforces Round #254 (Div. 1) -- C. DZY Loves Colors(分块)
- Codeforces Round #254 (Div. 1) C. DZY Loves Colors
- Codeforces Round #254 (Div. 2) E. DZY Loves Colors(线段树 成段更新)
- 【CodeForces】444C DZY Loves Colors 线段树
- 【线段树】 codeforces 444C DZY Loves Colors
- codeforces 444 C. DZY Loves Colors(线段树)
- Codeforces 444C DZY Loves Colors(线段树)
- codeforces 444C DZY Loves Colors 线段树乱搞
- Codeforces 444C DZY Loves Colors 线段树
- Codeforces 444C DZY Loves Colors 线段树
- codeforces 444C DZY Loves Colors(线段树)
- Codeforces 444C DZY Loves Colors(线段树)
- Codeforces 444C DZY Loves Colors 线段树区间更新
- CodeForces 444C - DZY Loves Colors(线段树)
- codeforces 444C. DZY Loves Colors (线段树)
- Codeforces Round #254 (Div. 2) C. DZY Loves Physics
- Java程序员笔试必备--Java基本概念
- Unity Android编译IL2CPP 对比 Mono
- linked-list-cycle
- UIScrollView 实现完美缩放
- Android studio中使用retrolambda之前的配置
- Codeforces Round #254 (Div. 1)C. DZY Loves Colors(线段树经典操作/分块)
- Java:String和Date、Timestamp之间的转换
- C++ list 的用法
- 欢迎使用CSDN-markdown编辑器
- laravel 获取当前路由的方法
- angularjs radio单选框
- Chrome网络服务器,用于Chrome测试本地网络应用程序
- Jquery中.data()基本用法
- Liunx就该这样学笔记整理(Liunx新手须知命令)