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/ ...
随机推荐
- Unity Development with VS Code
https://code.visualstudio.com/Docs/runtimes/unity
- C#中精确计时的一点收获 【转】
C#中精确计时的一点收获 [转] 以下所有代码运行环境:Windows 2003, Intel(R) Core(TM) 2 Duo CPU E8400 @ 3.00GHz 2.99GHz,2.96G ...
- EF 增删改
一.新增 UserInfo user = new UserInfo() { UserName = "jamsebing", UserPass = " }; db.User ...
- ThinkPHP中疑难笔记
不但要记住核心的东西, 还要记住 相关的 东西: 如php cli的版本是 5.6.14 bulit: sep 30, 2015 tp中, 通常说的系统就是框架; 项目就是 "应用程序&qu ...
- Java 判断整数方法
今天写代码的时候突然想到要怎么来判断整数,然后通过判断是否是整数来处理相关的操作.开始想到了几个方法,比如百度到的 x(int) instanceof Integer,但是这样的话程序会报错,还有一个 ...
- angularjs中父,子,兄之间controller值得传递
使用angularjs,发现controller间的值传递,比较麻烦的,以后几篇文章会陆续说几种方法. 一,angularjs $broadcast $emit $on的处理思想 在一个control ...
- JavaScript从父页面获取子页面的值(子页面又如何访问父页面)
之前还真没做过类似的东西,,top页面获取子页面的document.. 在百度搜了下即找到这个东东,还好,能用. 主要就是使用 contentWindow方法,获取子页面的所有document,再做处 ...
- Linux进程间通信(六):共享内存 shmget()、shmat()、shmdt()、shmctl()
下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...
- WDCP突破phpmyadmin导入文件时只有20M
WDCP在默认的配置下,PHPMYADMIN的上传上限是20M,很多时候我们的数据库大小已经大于了20M了,那这时候改怎么办呢?下面就用简单的话,告诉大家如何解决这一个问题.方法: 登录到WDCP的后 ...
- [Keygen]IntelliJ IDEA 14.1.7
IntelliJ IDEA 14.1.7 Keygen package com.candy.keygen.intelliJIdea; import java.math.BigInteger; impo ...