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. Dapper and Repository Pattern in MVC

    大家好,首先原谅我标题是英文的,因为我想不出好的中文标题. 这里我个人写了一个Dapper.net 的Repository模式的底层基础框架. 涉及内容: Dapper.net结合Repository ...

  2. MySQL 获取物理表的主键字段

    参考代码: /** * 获取主键字段 * @param $table * @param $database * @return mixed */ public function get_primary ...

  3. python 函数 闭包 (节省内存空间 html 获取网页的源码)

    #闭包:嵌套函数,内部函数调用外部函数的变量 # def outer(): # a = 1 # def inner(): # print(a) # inner() # outer() def oute ...

  4. linux socketpair

    相对于无名管道来说,socketpair也是使用在亲缘进程之间,不过它提供了能够全双工通信的通道 man socketpair: #include <sys/types.h> /* See ...

  5. oracle11g导出表时空表导不出解决方案

    oracle11g用exp命令导出数据库表时,有时会发现只导出了一部分表时而且不会报错,原因是有空表没有进行导出,之前一直没有找到方法于是用最笨的方法重新建这些空表,当然在我们实际当中表的数量大时我们 ...

  6. Git-Git协同与工作协同

    Git支持的协议 首先来看看数据交换需要使用的协议. Git提供了丰富的协议支持,包括:SSH.GIT.HTTP.HTTPS.FTP.FTPS.RSYNC及前面已经看到的本地协议等.各种不同协议的UR ...

  7. 十一、mysql老是停止运行该怎么解决

    mysql老是停止运行该怎么解决 你可能还会遇到无法启动mysql的错误 解决方法如下:      

  8. WCF入门二[WCF的配置文件]

    一.概述 往往在很多项目中数据库连接字符串.变量和一些动态的加载类会写在配置文件中.WCF也会在配置文件中写入一些配置参数,比如服务的地址.服务用于发送和接收消息的传输和消息编码等,通过配置文件可以灵 ...

  9. Ubuntu设置root密码[repost]

    From: http://hi.baidu.com/busybox/item/283e7d31433db7179cc65ef3 安装完Ubuntu后在终端使用命令:su -然后输入密码,总是不正确.原 ...

  10. 转载: keepalived工作原理和配置说明

    转自:http://outofmemory.cn/wiki/keepalived-configuration keepalived是什么 keepalived是集群管理中保证集群高可用的一个服务软件, ...