题意:

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; }

四个函数,对应四种操作A、B、C、S给出m个操作,求s操作时返回的结果。

分析:

明显的线段树的区间更新,但懒惰标记的选择要想一想,C这个操作好处理、我们观察A、B发现都是加上一个等差数列、等差数列加等差数列还是等差数列、那我们选择等差数列的首项和公差做标记。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<1|1
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
#define N 250001
const ll INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod = ;
struct node{
ll a1,d,sum,setv;
int l,r;
}t[N<<];
void pushup(int rt){
t[rt].sum=t[rt<<].sum+t[rt<<|].sum;
}
void pushdown(int rt){
if(t[rt].setv!=INF){
t[rt<<].setv=t[rt<<|].setv=t[rt].setv;
t[rt<<].a1=t[rt<<].d=t[rt<<|].a1=t[rt<<|].d=;
t[rt<<].sum=1LL*(t[rt<<].r-t[rt<<].l+)*t[rt].setv;
t[rt<<|].sum=1LL*(t[rt<<|].r-t[rt<<|].l+)*t[rt].setv;
t[rt].setv=INF;
}
if(t[rt].a1||t[rt].d){
ll len1=t[rt<<].r-t[rt<<].l+;
ll len2=t[rt<<|].r-t[rt<<|].l+;
ll tmp1=t[rt].a1;
ll tmp2=tmp1+len1*t[rt].d;
t[rt<<].a1+=tmp1;
t[rt<<|].a1+=tmp2;
t[rt<<].d+=t[rt].d;
t[rt<<|].d+=t[rt].d;
t[rt<<].sum+=tmp1*len1+len1*(len1-)/*t[rt].d;//等差数列求和
t[rt<<|].sum+=tmp2*len2+len2*(len2-)/*t[rt].d;
t[rt].a1=t[rt].d=;
}
}
void build(int l,int r,int rt){
t[rt].l=l;
t[rt].r=r;
t[rt].sum=t[rt].a1=t[rt].d=;
t[rt].setv=INF;
if(l==r)return;
int m=(l+r)>>;
build(lson);
build(rson);
pushup(rt);
}
void update_add(int l,int r,int rt,ll d){
if(l<=t[rt].l&&r>=t[rt].r){
ll a1=(d==)?(t[rt].l-l+):(r-t[rt].l+);//确定首项
ll len=t[rt].r-t[rt].l+;
t[rt].a1+=a1;
t[rt].d+=d;
t[rt].sum+=a1*len+len*(len-)/*d;
return;
}
pushdown(rt);
int m=(t[rt].l+t[rt].r)>>;
if(l<=m)update_add(l,r,rt<<,d);
if(r>m)update_add(l,r,rt<<|,d);
pushup(rt);
}
void update_set(int l,int r,int rt,ll x){
if(l<=t[rt].l&&r>=t[rt].r){
t[rt].setv=x;
t[rt].a1=t[rt].d=;
t[rt].sum=1LL*(t[rt].r-t[rt].l+)*x;
return;
}
pushdown(rt);
int m=(t[rt].l+t[rt].r)>>;
if(l<=m)update_set(l,r,rt<<,x);
if(r>m)update_set(l,r,rt<<|,x);
pushup(rt);
}
ll query(int l,int r,int rt){
if(l<=t[rt].l&&r>=t[rt].r){
return t[rt].sum;
}
pushdown(rt);
ll num=;
int m=(t[rt].l+t[rt].r)>>;
if(l<=m)num+=query(l,r,rt<<);
if(r>m)num+=query(l,r,rt<<|);
return num;
}
int main()
{
int n,tll,trr;
ll x;
char op[];
build(,N,);
scanf("%d",&n);
while(n--){
scanf("%s%d%d",op,&tll,&trr);
if(op[]=='A'){
update_add(tll,trr,,);
}
else if(op[]=='B')
update_add(tll,trr,,-);
else if(op[]=='C'){
scanf("%lld",&x);
update_set(tll,trr,,x);
}
else if(op[]=='S'){
printf("%lld\n",query(tll,trr,));
}
}
return ;
}

UVA 12436-Rip Van Winkle's Code(线段树的区间更新)的更多相关文章

  1. Uva 12436 Rip Van Winkle's Code

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

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

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

  3. 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 ...

  4. hdu 1556:Color the ball(线段树,区间更新,经典题)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  5. hdu 1698:Just a Hook(线段树,区间更新)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. hdu1698线段树的区间更新区间查询

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  7. HDU 1556 Color the ball(线段树:区间更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=1556 题意: N个气球,每次[a,b]之间的气球涂一次色,统计每个气球涂色的次数. 思路: 这道题目用树状数组和 ...

  8. zoj3686(线段树的区间更新)

    对线段树的区间更新有了初步的了解... A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a ...

  9. Color the ball (线段树的区间更新问题)

    N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色.但 ...

随机推荐

  1. 微软职位内部推荐-Pricipal Dev Manager for Application Ecosystem & Service

    微软近期Open的职位: Location: China, BeijingDivision: Operations System Group Engineering Group OverviewOSG ...

  2. jquery 数组和字典

    1 数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限, ...

  3. 团体程序设计天梯赛-练习集L1-002. 打印沙漏

    L1-002. 打印沙漏 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给 ...

  4. linq集合内部赋值

    linq集合内部赋值 比如将一个列的值,赋值给另一列 有三种方法: 1. e.Result.ToList().ForEach(n => n.IsIntermediarybool = SetIsI ...

  5. linux useradd添加用户

    useradd命令用来建立用户帐号和创建用户的起始目录,使用权限是超级用户. useradd -m -s /bin/bash -g 群组名 用户名 其中 -m:自动建立用户的登入目录. -s:指定用户 ...

  6. ue标签不见了,如何解决?

    小问题,但是很恶心...如下图: 解决方法: 右键点击[菜单栏]右边的空白处,选择advanced,默认是basic,这时菜单栏中的菜单条目会变多,然后选择[视图]---[视图/列表]---[打开文件 ...

  7. codeforces #305 div1 done

    总算搞定了这一场比赛的题目,感觉收获蛮大 其中A,B,C都能通过自己的思考解决掉 D题思路好神,E题仔细想想也能想出来 以后坚持每两天或者一天做一场CF的div1的全套题目 除非有实在无法做出来的题目 ...

  8. Qt: 绘图基础(非常简洁明了,全面)

    QPainter 能绘制: point, line, rectangle, ellipse, arc, chord, polygon, pie segment, Bezier curve, QPixm ...

  9. Android中Input型输入设备驱动原理分析<一>

    话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反正这个是没变的,在android的底层开发中对于Linux的基本驱动程序设计还是没变的,当然Android底层机制也 ...

  10. ubuntu12.04 make xconfig出错解决

    xconfig是linux下X Window环境中用于配制的一个工具,和menuconfig相似,但用法更友好方便,用如下命令可以进入配制界面: make xconfig 因为在ubuntu系统中,编 ...