CodeForces 444C 分块
题目链接:http://codeforces.com/problemset/problem/444/C
题意:给定一个长度为n的序列a[]。起初a[i]=i,然后还有一个色度的序列b[],起初b[i]=0。现在有2种操作:
1 l r x:区间染色,a[l],a[l+1]...a[r]变成x.同时b[l],b[l+1]...b[r]加上对应的|x-a[i]|值。
2 l r:统计区间和,统计区间b[l],b[l+1]...b[r]的和。
思路:线段树是比较常见的做法。考虑分块。每块维护一个lazy表示是否整块颜色都相同,Bsum表示块的b[i]总和.lazyb表示块的b[i]累加值的和。然后暴力维护即可。
#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<math.h>
#include<time.h>
#include<vector>
#include<iostream>
#include<map>
using namespace std;
typedef long long int LL;
const int MAXN = + ;
int belong[MAXN], block, num, L[MAXN], R[MAXN];
int n, q;
LL a[MAXN],b[MAXN];
struct Node{
LL lazy, Bsum,lazyb;
}Bval[];
void build(){
block = (int)sqrt(n + 0.5);
num = n / block; if (n%block){ num++; }
for (int i = ; i <= num; i++){
Bval[i].Bsum = ; Bval[i].lazy = ; Bval[i].lazyb=;
L[i] = (i - )*block + ; R[i] = i*block;
}
R[num] = n;
for (int i = ; i <= n; i++){
belong[i] = ((i - ) / block) + ;
}
}
void modify(int st, int ed,int val){
if (belong[st] == belong[ed]){
if(Bval[belong[st]].lazy){
for(int i=L[belong[st]];i<=R[belong[st]];i++){
a[i]=Bval[belong[st]].lazy;
}
Bval[belong[st]].lazy=;
}
for(int i=st;i<=ed;i++){
Bval[belong[st]].Bsum+=abs(a[i]-val);
b[i]+=abs(a[i]-val);
a[i]=val;
}
return;
}
if(Bval[belong[st]].lazy){
for(int i=L[belong[st]];i<=R[belong[st]];i++){
a[i]=Bval[belong[st]].lazy;
}
Bval[belong[st]].lazy=;
}
for (int i = st; i <= R[belong[st]]; i++){
Bval[belong[st]].Bsum+=abs(val-a[i]);
b[i]+=abs(val-a[i]);
a[i]=val;
}
for (int i = belong[st] + ; i < belong[ed]; i++){
if(Bval[i].lazy){
Bval[i].lazyb+=abs(val-Bval[i].lazy);
Bval[i].Bsum+=(1LL*abs(Bval[i].lazy-val)*(R[i]-L[i]+));
Bval[i].lazy=val;
}
else{
for(int j=L[i];j<=R[i];j++){
b[j]+=abs(a[j]-val);
Bval[i].Bsum+=abs(a[j]-val);
a[j]=val;
}
Bval[i].lazy=val;
}
}
if(Bval[belong[ed]].lazy){
for(int i=L[belong[ed]];i<=R[belong[ed]];i++){
a[i]=Bval[belong[ed]].lazy;
}
Bval[belong[ed]].lazy=;
}
for (int i = L[belong[ed]]; i <= ed; i++){
Bval[belong[ed]].Bsum+=abs(val-a[i]);
b[i]+=abs(val-a[i]);
a[i]=val;
}
}
LL query(int st, int ed){
LL ans = ;
if (belong[st] == belong[ed]){
for (int i = st; i <= ed; i++){
ans += (b[i]+Bval[belong[st]].lazyb);
}
return ans;
}
for (int i = st; i <= R[belong[st]]; i++){
ans += (b[i]+Bval[belong[st]].lazyb);
}
for (int i = belong[st] + ; i < belong[ed]; i++){
ans += Bval[i].Bsum;
}
for (int i = L[belong[ed]]; i <= ed; i++){
ans += (b[i]+Bval[belong[ed]].lazyb);
}
return ans;
}
int main(){
//#ifdef kirito
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
//#endif
// int start = clock();
while (~scanf("%d%d", &n,&q)){
for (int i = ; i <= n; i++){ a[i]=i; b[i]=;}
build();
int type, l, r, v;
for (int i = ; i <= q; i++){
scanf("%d", &type);
if (type == ){
scanf("%d%d%d", &l, &r,&v);
modify(l, r,v);
}
else{
scanf("%d%d", &l, &r);
printf("%lld\n", query(l, r));
}
}
}
//#ifdef LOCAL_TIME
// cout << "[Finished in " << clock() - start << " ms]" << endl;
//#endif
return ;
}
CodeForces 444C 分块的更多相关文章
- Codeforces 444C DZY Loves Colors(线段树)
题目大意:Codeforces 444C DZY Loves Colors 题目大意:两种操作,1是改动区间上l到r上面德值为x,2是询问l到r区间总的改动值. 解题思路:线段树模板题. #inclu ...
- CodeForces 455D 分块
题目链接:http://codeforces.com/problemset/problem/455/D 题意:给定一个长度为n的序列a[]. m次操作.共有两种操作 1 l r:将序列的a[l].a[ ...
- CodeForces 551E 分块
题目链接:http://codeforces.com/problemset/problem/551/E 题意:给定一个长度为N的序列. 有2个操作 1 l r v:序列第l项到第r项加v(区间加), ...
- CodeForces 103D 分块处理
题目链接:http://codeforces.com/problemset/problem/103/D 题意:给定一个长度为n的序列.然后q个询问.每个询问为(a,b),表示从序列第a项开始每b项的加 ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 828E) - 分块
Everyone knows that DNA strands consist of nucleotides. There are four types of nucleotides: "A ...
- CodeForces 13E 分块
题目链接:http://codeforces.com/problemset/problem/13/E 题意:给定n个弹簧和每个弹簧初始的弹力a[].当球落在第i个位置.则球会被弹到i+a[i]的位置. ...
- Serega and Fun CodeForces - 455D (分块 或 splay)
大意:给定n元素序列, 2种操作 将区间$[l,r]$循环右移1位 询问$[l,r]$中有多少个等于k的元素 现在给定q个操作, 输出操作2的询问结果, 强制在线 思路1: 分块 每个块内维护一个链表 ...
- CodeForces 444C 线段树
想分块想了很久一点思路都没有,结果一看都是写的线段树= = ...完全忘记了还有线段树这种操作 题意:给一个数组,一种操作是改变l到r为c,还有一种操作是查询l到r的总和差 线段树记得+lazy标记 ...
- CodeForces 444C. DZY Loves Physics(枚举+水题)
转载请注明出处:http://blog.csdn.net/u012860063/article/details/37509207 题目链接:http://codeforces.com/contest/ ...
随机推荐
- 基于 Arduino 的 RFID 识别实验
http://www.it165.net/embed/html/201512/3287.html 2015年12月04日(周五) 上午 博士的智能卡实验--RFID识别实验,基于51单片机: 我们的 ...
- 迅雷9、迅雷极速版之迅雷P2P加速:流量吸血鬼?为什么你装了迅雷之后电脑会感觉很卡很卡?
原文地址:http://www.whosmall.com/post/90 关闭极速版迅雷ThunderPlatform.exe进程 ThunderPlatform.exe目的:利用P2P技术进行用户间 ...
- js中的逻辑与(&&)和逻辑或(||)
之前有一个同事去面试,面试过程中碰到这样一个问题: 在js中写出如下的答案 : var a = 2; var b = 3; var andflag = a && b ; var orf ...
- 创立一个网站的前前后后(起因,域名,云平台,备案,CDN等等)(1)
起因 写完<完美软件开发:方法与逻辑>这书后,原本想继续写书的,可出来参加了些社区活动后,我发现我写的书大家评价还行,但其实不太理解.而接下来想写的书更加抽象点,准备叫<管理的解析& ...
- Digital calculation
No1=1 No2=2 1. let result=No1+No2 let No1++ let No1+=3 2. result=$[No1+No2] 3. result=$((No1+No ...
- Linux进程间通信(七):消息队列 msgget()、msgsend()、msgrcv()、msgctl()
下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信 -- 使用命名管道 一.什么是消息队列 消息队列提 ...
- Go - 字典(map)
字典是一种内置的数据结构,用来保存 键值对 的 无序集合. (1)字典的创建 1) make(map[KeyType] ValueType, initialCapacity) 2) make(map[ ...
- php中几个字符串替换函数详解
在php中字符替换函数有几个如有:str_replace.substr_replace.preg_replace.preg_split.str_split等函数,下面我来给大家总结介绍介绍. 一.st ...
- 数组去重及数组的prototype原型
Array.prototype.check= function(){ for(var i=0;i<this.length;i++){ for(var j=i+1;j<this.length ...
- python接收图片变成缩略图
python图像处理库:Pillow初级教程 Image类 Pillow中最重要的类就是Image,该类存在于同名的模块中.可以通过以下几种方式实例化:从文件中读取图片,处理其他图片得到,或者直接创建 ...