题意:

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. cocos2dx之C++调用Lua

    原文地址:http://blog.csdn.net/dingkun520wy/article/details/49839701 1.引入头文件 #include "cocos2d.h&quo ...

  2. crontab定时任务中文乱码问题

    手动执行都很正常的的脚本,添加到定时任务中日志文件全是乱码经过多方查证终于找到了原因! crontab启动的任务没有获取系统的环境变量,导致中文乱码解决办法:   在执行的脚步中添加编码方式或者添加对 ...

  3. hdu 4190

    二分求箱子中的票数  然后判是否满足条件     主要为了纪念一下用优先队列9000ms水过 #include<cstdio> #include<climits> #inclu ...

  4. Flume学习——BasicTransactionSemantics

    org.apache.flume.channel.BasicTransactionSemantics An implementation of basic Transaction semantics ...

  5. SOCI、LiteSQL、POCO数据库访问类库对比

    最近在做视频的开发,其中视频的设备接入管理服务器.流媒体管理服务器.中心服务器都涉及到了数据库的操作,同时需要兼容大多数版本的数据库,包括mysql.sqlite.oracle.公司原来使用的是ado ...

  6. linux命令补全 忘记命令只记得开头

    linux的shell不仅提供上下箭头来翻阅历史使用过的命令,还提供命令补全功能. 例如,你想创建一个文件夹,只记得是m开头的命令,此时可以: ①输入m ②按键盘上的Tab键两次 (有可能还出现这句话 ...

  7. Source Insight的应用技巧、宏功能

    目录 1 简介... 5 2 搭建我们的SI环境... 5 2.1 搭建步骤... 5 2.2 说明... 6 3 应用技巧... 6 3.1 初级应用技巧... 6 3.1.1 解决字体不等宽与对齐 ...

  8. Qt之界面数据存储与获取(使用setUserData()和userData())

    在GUI开发中,往往需要在界面中存储一些有用的数据,这些数据可以来配置文件.注册表.数据库.或者是server. 无论来自哪里,这些数据对于用户来说都是至关重要的,它们在交互过程中大部分都会被用到,例 ...

  9. C#连接SQLite的字符串

    一.C#在不同情况下连接SQLite字符串格式 1.Basic(基本的) Data Source=filename;Version=3; 2.Using UTF16(使用UTF16编码) Data S ...

  10. 208. Implement Trie (Prefix Tree)

    题目: Implement a trie with insert, search, and startsWith methods. 链接: http://leetcode.com/problems/i ...