Problem J: Alex’s Foolish Function

Time Limit: 8 Sec  Memory Limit: 128 MB
Submit: 18  Solved: 2

Description

Alex has an array F which size is n, initially each element’s value is zero. Now he wants to operate the array, he has 4 different functions:
1) Function A(l, r):
Add the elements between l to r (inclusive) where the ith add i - l + 1, for instance, if l is 4,
r is 6 and the elements between 4 to 6 is 3 4 10, after this operation, these elements will become 4 6 13.
2) Function B(l, r):
Add the elements between l to r (inclusive) where the ith add r - i + 1, for instance, if l is 4,
r is 6 and the elements between 4 to 6 is 3 4 10, after this operation, these elements will become 6 6 11.
3) Function C(l, r, x):
Set all the elements(between l to r) to x, for instance, if l is 4, r is 6 and the elements
between 4 to 6 is 3 4 10, and x = 2, after this operation, these elements will become 2 2 2.
4) Function S(l, r):
Output Fl + Fl+1 + Fl+2 + ...+ Fr. 

Input

Input start with an integer T(1 <= T <= 5), denoting the number of test case.
For each test case, first line contains n, m (1 <= n <= 200000, 1 <= m <= 100000), denoting the array’size and the number of operations.
Next m lines, each line contains an operation, formatting as
A l r
B l r
C l r x
S l r 

Output

For each S Function operations, output the sum. 

Sample Input

1
5 4
A 1 3
B 2 5
C 1 1 2
S 1 5

Sample Output

17

正规做法是线段树维护区间的左加、右加或者覆盖信息,然而想用分块写一写。

对于A操作,每一个块维护起始的加数,以及A操作的次数,

对于B操作,每一个块维护末尾的加数,以及B操作的次数,

对于C操作,每一个块维护准备覆盖的值val。

显然对于A操作和B操作维护的信息,是满足区间加法的,即[1,4]A操作一次,[2,4]A操作一次,比如当前块是[2,4],记为Bx,那么我们可以记录起始的加数:(2-1+1)+(2-2+1)=3,A操作次数为2,即arr[2]+=3,arr[3]+=(3+2),arr[4]+=(3+2+2),然后我们可以发现这是一个等差数列,可以用公式快速得到有延迟标记A操作的区间和,即$(Bx.lazy_A+(Bx.lazy_A+Bx.len-1))*Bx.len/2+Bx.sum$,然后B操作也同理,最后加上本身的$Bx.sum$即可(这里要注意AB操作不能重复加Bx.sum);B操作同理;C操作的话由于是覆盖那么在更新的时候把更新到的块的$lazy_c$更新,并把$lazy_A$与$lazy_B$取消掉即可,由于可能$lazy_c$为0,初始值应设为一个不太可能用到的数,比如$-INF$。

代码:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 200010;
const int M = 450;
struct Block
{
int l, r;
LL lazy1, lazy2, lazy3, sum;
LL c1, c2; inline int len()
{
return r - l + 1;
}
};
Block B[M];
LL arr[N];
int belong[N], unit, bcnt;
int n, m; void init()
{
int i;
unit = sqrt(n);
bcnt = n / unit;
if (n % unit)
++bcnt;
for (i = 1; i <= bcnt; ++i)
{
B[i].l = (i - 1) * unit + 1;
B[i].r = i * unit;
B[i].sum = 0LL;
B[i].lazy1 = 0LL;
B[i].lazy2 = 0LL;
B[i].lazy3 = -INF;
B[i].c1 = B[i].c2 = 0LL;
}
B[bcnt].r = n;
for (i = 1; i <= n; ++i)
{
arr[i] = 0LL;
belong[i] = (i - 1) / unit + 1;
}
}
void pushdown(int bx)
{
if (B[bx].lazy3 != -INF)
{
for (int i = B[bx].l; i <= B[bx].r; ++i)
arr[i] = B[bx].lazy3;
B[bx].lazy3 = -INF;
}
if (B[bx].lazy1)
{
for (int i = B[bx].l; i <= B[bx].r; ++i)
{
arr[i] += + B[bx].lazy1;
B[bx].lazy1 += B[bx].c1;
}
B[bx].lazy1 = 0LL;
B[bx].c1 = 0LL;
}
if (B[bx].lazy2)
{
for (int i = B[bx].r; i >= B[bx].l; --i)
{
arr[i] += + B[bx].lazy2;
B[bx].lazy2 += B[bx].c2;
}
B[bx].lazy2 = 0LL;
B[bx].c2 = 0LL;
}
B[bx].sum = 0LL;
for (int i = B[bx].l; i <= B[bx].r; ++i)
B[bx].sum += arr[i];
}
void update(int l, int r, int ops, LL val = 0LL)
{
int bl = belong[l], br = belong[r];
int i;
if (bl == br)
{
pushdown(bl);
if (ops == 1)
{
for (i = l; i <= r; ++i)
{
B[bl].sum -= arr[i];
arr[i] = arr[i] + (LL)(i - l + 1LL);
B[bl].sum += arr[i];
}
}
else if (ops == 2)
{
for (i = r; i >= l; --i)
{
B[bl].sum -= arr[i];
arr[i] = arr[i] + (LL)(r - i + 1LL);
B[bl].sum += arr[i];
}
}
else if (ops == 3)
{
for (i = l; i <= r; ++i)
{
B[bl].sum -= arr[i];
arr[i] = val;
B[bl].sum += arr[i];
}
}
}
else
{
//left
pushdown(bl);
if (ops == 1)
{
for (i = l; i <= B[bl].r; ++i)
{
B[bl].sum -= arr[i];
arr[i] = arr[i] + (LL)(i - l + 1LL);
B[bl].sum += arr[i];
}
}
else if (ops == 2)
{
for (i = B[bl].r; i >= l; --i)
{
B[bl].sum -= arr[i];
arr[i] = arr[i] + (LL)(r - i + 1LL);
B[bl].sum += arr[i];
}
}
else if (ops == 3)
{
for (i = l; i <= B[bl].r; ++i)
{
B[bl].sum -= arr[i];
arr[i] = val;
B[bl].sum += arr[i];
}
}
//right
pushdown(br);
if (ops == 1)
{
for (i = B[br].l; i <= r; ++i)
{
B[br].sum -= arr[i];
arr[i] = arr[i] + (LL)(i - l + 1LL);
B[br].sum += arr[i];
}
}
else if (ops == 2)
{
for (i = r; i >= B[br].l; --i)
{
B[br].sum -= arr[i];
arr[i] = arr[i] + (LL)(r - i + 1LL);
B[br].sum += arr[i];
}
}
else if (ops == 3)
{
for (i = B[br].l; i <= r; ++i)
{
B[br].sum -= arr[i];
arr[i] = val;
B[br].sum += arr[i];
}
}
for (i = bl + 1; i < br; ++i)
{
if (ops == 3)
{
B[i].lazy3 = val;
B[i].c1 = 0LL;
B[i].c2 = 0LL;
B[i].lazy1 = 0LL;
B[i].lazy2 = 0LL;
}
else if (ops == 2)
{
B[i].lazy2 += (LL)(r - B[i].r + 1LL);
++B[i].c2;
}
else if (ops == 1)
{
B[i].lazy1 += (LL)(B[i].l - l + 1LL);
++B[i].c1;
}
}
}
}
LL query(int l, int r)
{
int bl = belong[l], br = belong[r], i;
LL sum = 0LL;
if (bl == br)
{
pushdown(bl);
for (i = l; i <= r; ++i)
sum += arr[i];
return sum;
}
else
{
pushdown(bl);
pushdown(br);
for (i = l; i <= B[bl].r; ++i)
sum += arr[i];
for (i = B[br].l; i <= r; ++i)
sum += arr[i];
for (i = bl + 1; i < br; ++i)
{
if (B[i].lazy3 != -INF)
sum += (LL)B[i].len() * B[i].lazy3;
if (B[i].lazy1)
sum += (B[i].lazy1 + B[i].lazy1 + (LL)(B[i].len() - 1LL) * B[i].c1) * (LL)B[i].len() / 2LL;
if (B[i].lazy2)
sum += (B[i].lazy2 + B[i].lazy2 + (LL)(B[i].len() - 1LL) * B[i].c2) * (LL)B[i].len() / 2LL;
if (B[i].lazy3 == -INF)
sum += B[i].sum;
}
return sum;
}
}
int main(void)
{
// fin("test0.in");
// fout("data_wa.txt");
int tcase, l, r, v;
char ops[4];
scanf("%d", &tcase);
while (tcase--)
{
scanf("%d%d", &n, &m);
init();
while (m--)
{
scanf("%s", ops);
if (ops[0] == 'A')
{
scanf("%d%d", &l, &r);
update(l, r, 1);
}
else if (ops[0] == 'B')
{
scanf("%d%d", &l, &r);
update(l, r, 2);
}
else if (ops[0] == 'C')
{
scanf("%d%d%d", &l, &r, &v);
update(l, r, 3, (LL)v);
}
else
{
scanf("%d%d", &l, &r);
printf("%lld\n", query(l, r));
}
}
}
return 0;
}

NBUT校赛 J Alex’s Foolish Function(分块+延迟标记)的更多相关文章

  1. QAU 17校赛 J题 剪丝带(完全背包变形)

    题意: 剪一段丝带,对于剪完后的每一段丝带长度必须是a,b,c 输入丝带的长度  n 和  a  b  c 输出一个整数,代表最多能剪成多少段 样例输入 5 5 3 2 7 5 5 2 样例输出 2 ...

  2. QAU 18校赛 J题 天平(01背包 判断能否装满)

    问题 J: 天平 时间限制: 1 Sec  内存限制: 128 MB提交: 36  解决: 9[提交][状态][讨论版][命题人:admin] 题目描述 天平的右端放着一件重量为w的物品.现在有n个重 ...

  3. 上海高校金马五校赛 J - 小Y写文章

    题目大意: 给你n个数字, 定义不连贯值为, max(abs(a[ i ] - b[ i ])) ,现在让你把m个新的数字插入n + 1 个空位中,使得不连贯值最小. 思路:二分不连贯值, 每次进行二 ...

  4. 福建工程学院第十四届ACM校赛J题题解

    第六集,想不到你这个浓眉大眼的都叛变革命了 题意: 给你两个只包含01的字符串S和T,问你在允许一次错误的情况下,T是否能成为S的子串 思路: 这个问题的解法挺多,我是用fft匹配的,也比较简单,针对 ...

  5. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  6. 2014上半年acm总结(1)(入门+校赛)

    大一下学期才开始了acm,不得不说有一点迟,但是acm确实使我的生活充实了很多,,不至于像以前一样经常没事干=  = 上学期的颓废使我的c语言学的渣的一笔..靠考前突击才基本掌握了语法 寒假突然醒悟, ...

  7. HZNU第十二届校赛赛后补题

    愉快的校赛翻皮水! 题解 A 温暖的签到,注意用gets #include <map> #include <set> #include <ctime> #inclu ...

  8. 牛客网多校赛第9场 E-Music Game【概率期望】【逆元】

    链接:https://www.nowcoder.com/acm/contest/147/E 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...

  9. 2014哈商大ICPC/ACM校赛解题报告

    被debug邀请去參加校赛,哎,被虐..我对不起工大.. 由于本人不搞ACM,算法处于HelloWorld水准.. 虽然题目除了鸟不拉屎星人之外都非常水,但我能做到这个程度,全然是超水平发挥了.. 数 ...

随机推荐

  1. Maven学习总结(10)

    本文通过一个例子来介绍利用maven来构建一个多模块的jave项目.开发工具:intellij idea. 一.项目结构 multi-module-project是主工程,里面包含两个模块(Modul ...

  2. ant Design表单验证笔记

    1.pattern正则验证 <Col md={12} sm={24}> <FormItem {...formItemLayout} label="班数"> ...

  3. 简单了解,使用oracle中的索引,表分区

    索引的分类 如下: 物理分类 逻辑分类 分区或非分区索引 单列或组合索引 B树索引(标准索引) 唯一或非唯一索引 正常或反向键索引 基于函数索引 位图索引   B树索引 b树索引通常也称为标准索引,索 ...

  4. Linux段式管理与页式管理

    内存管理有2种机制:1.段式管理:2.页式管理 在80386CPU中增加了2个寄存器:1.全局性的段描述表寄存器GDTR 2.局部性的段描述表寄存器LDTR 段寄存器的高13位用于在全局或局部描述表项 ...

  5. Effective Approaches to Attention-based Neural Machine Translation(Global和Local attention)

    这篇论文主要是提出了Global attention 和 Local attention 这个论文有一个译文,不过我没细看 Effective Approaches to Attention-base ...

  6. Python学习笔记:Matplotlib(数据可视化)

    Matplotlib是一个可以将数据绘制为图形表示的Python三方库,包括线性图(折线图,函数图).柱形图.饼图等基础而直观的图形,在平常的开发当中需要绘图时就非常有用了. 安装:pip insta ...

  7. C# 窗口关闭事件

    首先添加一个退出事件函数 //退出按键 private void Form1_FormClosing(object sender, FormClosingEventArgs e) { DialogRe ...

  8. Error: Cannot find module 'core-js/fn/array/values' at Function.Module._resolveFilename (module

    E:\codeBase\top605\rescue-master\server\node_modules\_log4js@1.1.1@log4js\lib\log4js.js:321 throw ne ...

  9. 用python实现【五猴分桃】问题

    转载链接:https://blog.csdn.net/cy309173854/article/details/78296839 据说“五猴分桃”问题最先是由大物理学家狄拉克提出来的,这一貌似简单的问题 ...

  10. Android log 引发的血案

    今天调试代码,我打印了一个东西: Log.d("WelcomeActivity", res.str); 结果总是代码执行不到这一行的下一行,程序也没有挂掉.后来,我自己去想各种可能 ...