Rip Van Winkle was fed up with everything except programming. One day he found a problem whichrequired to perform three types of update operations (A, B, C), and one query operation S over an arraydata[]. Initially all elements of data are equal to 0. Though
Rip Van Winkle is going to sleep for 20years, and his code is also super slow, you need to perform the same update operations and output theresult for the query operation S in an efficient way.

long long data[250001];

void A( int st, int nd ) {

for( int i = st; i \le nd; i++ ) data[i] = data[i] + (i - st + 1);

}

void B( int st, int nd ) {

for( int i = st; i \le nd; i++ ) data[i] = data[i] + (nd - i + 1);

}

void C( int st, int nd, int x ) {

for( int i = st; i \le nd; i++ ) data[i] = x;

}

long long S( int st, int nd ) {

long long res = 0;

for( int i = st; i \le nd; i++ ) res += data[i];

return res;

}

Input

The first line of input will contain T (≤ 4 ∗ 105) denoting the number of operations. Each of the nextT lines starts with a character (‘A’, ‘B’, ‘C’ or ‘S’), which indicates the type of operation. Character ‘A’,‘B’ or ‘S’ will be followed by two integers,
st and nd in the same line. Character ‘C’ is followed by threeintegers, st, nd and x. It’s assumed that, 1 ≤ st ≤ nd ≤ 250000 and −105 ≤ x ≤ 105. The meaningsof these integers are explained by the code of Rip Van Winkle.

Output

For each line starting with the character ‘S’, print S(st, nd) as defined in the code.

Sample Input

7

A 1 4

B 2 3

S 1 3

C 3 4 -2

S 2 4

B 1 3

S 2 4

Sample Output

9

0

3

这题是区间更新,这题比较麻烦,做了很长时间。先用线段树维护l,r,add1(线段左端点加的值),add2(线段右端点加的值),step(区间的公差,右边减去左边的),sum(区间总和),flag(判断区间是否数字相同),value(区间数字都相同时的数值大小).我的思路是每一次更新,都把这一段的sum值直接表示出来,如果更新的这条线段小于当前线段,那么先不更新sum值,而是b[th].sum=b[lth].sum+b[rth].sum;

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define lth th<<1
#define rth th<<1|1
#define inf 99999999
#define pi acos(-1.0)
#define MOD 100000007
#define maxn 250050
struct node{
int l,r;
ll value,flag; //flag表示这段是不是值都是相同的,value是这段的值
ll add1,step,add2; //add1表示左端点加的值,add2表示右端点,step表示这段的公差
ll sum;
}b[4*maxn]; void build(int l,int r,int th)
{
int mid;
b[th].l=l;b[th].r=r;
b[th].value=0;b[th].flag=1;
b[th].add1=b[th].step=b[th].add2=0;
b[th].sum=0;
if(l==r)return;
mid=(l+r)/2;
build(l,mid,lth);
build(mid+1,r,rth);
}
void pushdown(int th)
{
int mid;
mid=(b[th].l+b[th].r)/2;
if(b[th].flag){
b[th].flag=0;
b[lth].flag=1;
b[lth].value=b[th].value;
b[lth].add1=b[lth].add2=b[lth].step=0;
b[lth].sum=(b[lth].r-b[lth].l+1)*b[th].value; b[rth].flag=1;
b[rth].value=b[th].value;
b[rth].add1=b[rth].add2=b[rth].step=0;
b[rth].sum=(b[rth].r-b[rth].l+1)*b[th].value;
} ll add1,add2;
add1=b[th].add1; add2=b[th].add1+(mid-b[th].l)*b[th].step;
b[lth].add1+=add1;
b[lth].add2+=add2;
b[lth].step+=b[th].step;
b[lth].sum+=(add1+add2)*(b[lth].r-b[lth].l+1)/2; ll add3,add4;
add3=add2+b[th].step;add4=add3+(b[th].r-(mid+1))*b[th].step;
b[rth].add1+=add3;
b[rth].add2+=add4;
b[rth].step+=b[th].step;
b[rth].sum+=(add3+add4)*(b[rth].r-b[rth].l+1)/2; b[th].add1=b[th].add2=b[th].step=0;
}
void pushup(int th)
{
b[th].sum=b[lth].sum+b[rth].sum;
} void update(int l,int r,ll add,int f,int th)
{
int mid;
if(b[th].l==l && b[th].r==r){
if(f==1){
b[th].add1+=add;
b[th].add2+=add+b[th].r-b[th].l;
b[th].step+=1;
b[th].sum+=(add+add+b[th].r-b[th].l)*(b[th].r-b[th].l+1)/2;
return;
}
else if(f==2){
b[th].add1+=add+b[th].r-b[th].l;
b[th].add2+=add;
b[th].step-=1;
b[th].sum+=(add+add+b[th].r-b[th].l)*(b[th].r-b[th].l+1)/2;
return;
}
else if(f==3){
b[th].flag=1;
b[th].value=add;
b[th].sum=b[th].value*(b[th].r-b[th].l+1);
b[th].add1=b[th].add2=b[th].step=0;
return;
}
}
pushdown(th);
mid=(b[th].l+b[th].r)/2;
if(r<=mid)update(l,r,add,f,lth);
else if(l>mid)update(l,r,add,f,rth);
else{
if(f==1){
update(l,mid,add,f,lth);
update(mid+1,r,add+(mid+1-l),f,rth);
}
else if(f==2){
update(l,mid,add+(r-mid),f,lth);
update(mid+1,r,add,f,rth);
}
else if(f==3){
update(l,mid,add,f,lth);
update(mid+1,r,add,f,rth);
}
}
pushup(th);
}
ll question(int l,int r,int th)
{
int mid;
if(b[th].l==l && b[th].r==r){
return b[th].sum;
}
pushdown(th);
mid=(b[th].l+b[th].r)/2;
if(r<=mid)return question(l,r,lth);
else if(l>mid)return question(l,r,rth);
else{
return question(l,mid,lth)+question(mid+1,r,rth);
}
}
int main()
{
int m,i,j,T,c,d;
ll n,num;
char s[10];
while(scanf("%lld",&n)!=EOF)
{
build(1,250010,1);
for(i=1;i<=n;i++){
scanf("%s%d%d",s,&c,&d);
if(s[0]=='A'){
update(c,d,1,1,1);
}
else if(s[0]=='B'){
update(c,d,1,2,1);
}
else if(s[0]=='C'){
scanf("%lld",&num);
update(c,d,num,3,1);
}
else if(s[0]=='S'){
printf("%lld\n",question(c,d,1) );
}
}
}
return 0;
}

Uva 12436 Rip Van Winkle's Code的更多相关文章

  1. UVA 12436 - Rip Van Winkle&#39;s Code(线段树)

    UVA 12436 - Rip Van Winkle's Code option=com_onlinejudge&Itemid=8&page=show_problem&cate ...

  2. Uva 12436 Rip Van Winkle&#39;s Code

    Rip Van Winkle was fed up with everything except programming. One day he found a problem whichrequir ...

  3. UVA-12436 Rip Van Winkle's Code (线段树区间更新)

    题目大意:一个数组,四种操作: long long data[250001]; void A( int st, int nd ) { for( int i = st; i <= nd; i++ ...

  4. UVA 12436-Rip Van Winkle's Code(线段树的区间更新)

    题意: long long data[250001]; void A( int st, int nd ) { for( int i = st; i \le nd; i++ ) data[i] = da ...

  5. 线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)

    转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnl ...

  6. UVALive 3989 Ladies' Choice(稳定婚姻问题:稳定匹配、合作博弈)

    题意:男女各n人,进行婚配,对于每个人来说,所有异性都存在优先次序,即最喜欢某人,其次喜欢某人...输出一个稳定婚配方案.所谓稳定,就是指未结婚的一对异性,彼此喜欢对方的程度都胜过自己的另一半,那么这 ...

  7. FLUENT多孔介质数值模拟设置【转载】

    转载自:http://zhengjun0228.blog.163.com/blog/static/71377014200971895419613/ 多孔介质条件 多孔介质模型可以应用于很多问题,如通过 ...

  8. 编译调试 .NET Core 5.0 Preview 并分析 Span 的实现原理

    很久没有写过 .NET Core 相关的文章了,目前关店在家休息所以有些时间写一篇新的

  9. UVA 11754 - Code Feat(数论)

    UVA 11754 - Code Feat 题目链接 题意:给定一个c个x, y1,y2,y3..yk形式,前s小的答案满足s % x在集合y1, y2, y3 ... yk中 思路:LRJ大白例题, ...

随机推荐

  1. python学习笔记 | PyCharm出现卡顿解决方法

    问题:使用pycharm时常出现 the IDE is running low on memory 的问题 表示pycharm这款IDE使用内存不足 需要在系统内存充足的情况下扩充IDE memory ...

  2. linux线程数限制与zabbix监控

    Linux最大线程数限制及当前线程数查询 最大线程数计算方式: n = total_memory/128k; Linux用户线程数限制而导致的程序异常为 java.lang.OutOfMemoryEr ...

  3. qmake奇淫技巧之字符串宏定义

    阅读本文大概需要3.3分钟 我们平时在软件开发过程中需要定义一些宏,以便在代码中调用,这样每次不需要修改代码,只需要修改外部编译命令就可以得到想要的参数,非常方便 比如我们想在软件介绍中显示软件版本, ...

  4. 【Oracle】Oracle 10g下载路径

    ORACLE 10g下载地址 下载方法: 直接复制下面的链接,打开迅雷,自动会识别下载的内容 Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise ...

  5. LeetCode617. 合并二叉树

    题目 1 class Solution { 2 public: 3 TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { 4 if(!t1 && ...

  6. springboot项目启动并立即执行自定义程序内容

    第一种:实现ApplicationRunner接口,重写其中的run()方法: 第二种:实现CommandLineRunner接口,重写其中的run()方法: 还有第三种...

  7. ROS教程(二):创建工作空间(图文)

    ros教程:创建工作空间 目录 前言 一.工作空间? 二.创建一个工作空间 1.创建目录 2.编译 前言 使用catkin创建一个工作空间 一.工作空间? 在ROS系统下,我们所有的项目都放在一个工作 ...

  8. centos系统磁盘扩容

    1.查看磁盘空间大小,使用df -h 命令. 2. 增加磁盘空间,例如下图使用VM虚拟机增加的方式.物理机直接安装挂载上去. 3. 使用fdisk /dev/sda, 创建新分区. 4.重启Linux ...

  9. Go RPC 框架 KiteX 性能优化实践 原创 基础架构团队 字节跳动技术团队 2021-01-18

    Go RPC 框架 KiteX 性能优化实践 原创 基础架构团队 字节跳动技术团队 2021-01-18

  10. What is the difference between Serialization and Marshaling?

    How to serialize and deserialize JSON using C# - .NET | Microsoft Docs https://docs.microsoft.com/en ...