You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15

题意:就是区间更改,区间求和。

思路:常规线段树,也可以树状态数组,也可以splay。

ps:我记得csl蔡神就是经常用splay来做线段树题,我最近发现这真是个好习惯。很大的好处就是写平衡树可以写得很灵活吧。

这里主要是都写一下,然后对比下效率。  也尽量以后多写splay。)

 体会:由于splay基本操作后都要把Now节点splay到根节点,可以从这里想办法优化。

比如,不要求在线的时候(比如区间第K大),可以向莫队一样,排序后再回答,这样,每次splay的高度会小一些。

其他优化就待续了,目前平衡树做得少。

树状数组:1969ms:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=;
ll a[maxn],b[maxn],c[maxn];
char opt[];int n,m;
int lowbit(int x) {return x&(-x);}
void add(ll *bb,ll *cc,int x,int val)
{
ll tmp=x*val;
for(int i=x;i<=n+;i+=lowbit(i))
bb[i]+=val,cc[i]+=tmp;
}
ll query(ll *bb,ll *cc,int x)
{
ll res=;
for(int i=x;i;i-=lowbit(i)) res+=bb[i]; res*=(x+);
for(int i=x;i;i-=lowbit(i)) res-=cc[i];
return res+a[x];
}
int main()
{
while(~scanf("%d%d",&n,&m)){
for(int i=;i<=n;i++) scanf("%lld",&a[i]),a[i]+=a[i-];
for(int i=;i<=n;i++) b[i]=c[i]=;
while(m--){
scanf("%s",opt); int x,y,z;
if(opt[]=='Q')scanf("%d%d",&x,&y),printf("%lld\n",query(b,c,y)-query(b,c,x-));
else scanf("%d%d%d",&x,&y,&z),add(b,c,x,z),add(b,c,y+,-z);
}
} return ;
}

线段树:2407ms:

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn=;
int n,m;int a[maxn];
struct TREE
{
ll sum[maxn<<];int lazy[maxn<<];
void build(int Now,int l,int r)
{
lazy[Now]=;
if(l==r) { sum[Now]=a[l]; return;}
int Mid=(l+r)>>;
build(Now<<,l,Mid);
build(Now<<|,Mid+,r);
pushup(Now);
}
void add(int Now,int l,int r,int x,int y,int val)
{
if(x<=l&&y>=r) { sum[Now]+=(ll)(r-l+)*val;lazy[Now]+=val; return ;}
pushdown(Now,l,r); int Mid=(l+r)>>;
if(y<=Mid) add(Now<<,l,Mid,x,y,val);
else if(x>Mid) add(Now<<|,Mid+,r,x,y,val);
else add(Now<<,l,Mid,x,Mid,val),add(Now<<|,Mid+,r,Mid+,y,val);
pushup(Now);
}
ll query(int Now,int l,int r,int x,int y)
{
if(x<=l&&y>=r) return sum[Now];
pushdown(Now,l,r); int Mid=(l+r)>>;
if(y<=Mid) return query(Now<<,l,Mid,x,y);
else if(x>Mid) return query(Now<<|,Mid+,r,x,y);
else return query(Now<<,l,Mid,x,Mid)+query(Now<<|,Mid+,r,Mid+,y);
pushup(Now);
}
void pushup(int Now) { sum[Now]=sum[Now<<]+sum[Now<<|];}
void pushdown(int Now,int l,int r)
{
int Mid=(l+r)>>;
lazy[Now<<]+=lazy[Now];sum[Now<<]+=(ll)(Mid-l+)*lazy[Now];
lazy[Now<<|]+=lazy[Now];sum[Now<<|]+=(ll)(r-Mid)*lazy[Now];
lazy[Now]=;
}
}Tree;
int main()
{
while(~scanf("%d%d",&n,&m)){
for(int i=;i<=n;i++) scanf("%d",&a[i]);
Tree.build(,,n);
for(int i=;i<=m;i++){
char opt[];int x,y,z;
scanf("%s",opt);
if(opt[]=='Q') scanf("%d%d",&x,&y),printf("%lld\n",Tree.query(,,n,x,y));
else scanf("%d%d%d",&x,&y,&z),Tree.add(,,n,x,y,z);
}
} return ;
}

splay:3891ms。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn=;
int a[maxn];
struct Splay
{
int ch[maxn][],sz[maxn],fa[maxn],rt,cnt;
ll sum[maxn],key[maxn],lazy[maxn];
void init()
{
rt=cnt=;
}
int get(int x)
{
return ch[fa[x]][]==x;
}
void pushdown(int Now)
{
if(!lazy[Now]) return ;
int cl=ch[Now][],cr=ch[Now][];
if(cl){
sum[cl]+=sz[cl]*lazy[Now];
lazy[cl]+=lazy[Now]; key[cl]+=lazy[Now];
}
if(cr){
sum[cr]+=sz[cr]*lazy[Now];
lazy[cr]+=lazy[Now]; key[cr]+=lazy[Now];
}
lazy[Now]=;
}
void update(int Now)
{
sum[Now]=key[Now]; sz[Now]=;
if(ch[Now][]) sum[Now]+=sum[ch[Now][]],sz[Now]+=sz[ch[Now][]];
if(ch[Now][]) sum[Now]+=sum[ch[Now][]],sz[Now]+=sz[ch[Now][]];
}
void rotate(int x)
{
int old=fa[x],fold=fa[old],opt=(ch[old][]==x);
pushdown(old); pushdown(x);
fa[ch[x][opt^]]=old; ch[old][opt]=ch[x][opt^];
ch[x][opt^]=old; fa[old]=x; fa[x]=fold;
if(!fold) rt=x;
else ch[fold][ch[fold][]==old]=x;
update(old); update(x);
}
void splay(int x,int y)
{
for(int f;(f=fa[x])!=y;rotate(x)){
if(fa[f]!=y)
rotate(get(x)==get(f)?f:x);
}
if(!y) rt=x;
}
int build(int L,int R)
{
if(L>R) return -;
int Mid=(L+R)>>;
if(!rt) rt=Mid;
key[Mid]=a[Mid]; sum[Mid]=a[Mid]; sz[Mid]=;
lazy[Mid]=fa[Mid]=ch[Mid][]=ch[Mid][]=;
int cl=build(L,Mid-);
if(cl!=-) {
ch[Mid][]=cl; fa[cl]=Mid; sz[Mid]+=sz[cl];
}
int cr=build(Mid+,R);
if(cr!=-){
ch[Mid][]=cr; fa[cr]=Mid; sz[Mid]+=sz[cr];
}
update(Mid);
return Mid;
}
ll query(int x,int y)
{
splay(x,); splay(y,x);
return sum[ch[ch[rt][]][]];
}
void change(int x,int y,int z)
{
splay(x,); splay(y,x);
int t=ch[ch[rt][]][];
key[t]+=z; lazy[t]+=z;
sum[t]+=sz[t]*z;
}
}S;
int main()
{
int N,Q,x,y,z; char opt[];
while(~scanf("%d%d",&N,&Q)){
S.init();
for(int i=;i<=N;i++) scanf("%d",&a[i+]); a[]=a[N+]=;
S.build(,N+);
while(Q--){
scanf("%s",opt);
if(opt[]=='C'){
scanf("%d%d%d",&x,&y,&z);
S.change(x,y+,z);
}
else {
scanf("%d%d",&x,&y);
printf("%lld\n",S.query(x,y+));
}
}
}
return ;
}

POJ3468:A Simple Problem with Integers (线段树||树状数组||Splay解决基本问题的效率对比)的更多相关文章

  1. poj3468 A Simple Problem with Integers (线段树区间最大值)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 92127   ...

  2. POJ3468 A Simple Problem with Integers 【段树】+【成段更新】

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 57666   ...

  3. POJ3468 A Simple Problem with Integers(线段树延时标记)

    题目地址http://poj.org/problem?id=3468 题目大意很简单,有两个操作,一个 Q a, b 查询区间[a, b]的和 C a, b, c让区间[a, b] 的每一个数+c 第 ...

  4. poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)

    转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...

  5. POJ3468 A Simple Problem with Integers —— 线段树 区间修改

    题目链接:https://vjudge.net/problem/POJ-3468 You have N integers, A1, A2, ... , AN. You need to deal wit ...

  6. 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和

    poj3468 A Simple Problem with Integers 题意:O(-1) 思路:O(-1) 线段树功能:update:成段增减 query:区间求和 Sample Input 1 ...

  7. 2018 ACMICPC上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节)

    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节) 链接:https://ac.nowcoder.co ...

  8. POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)

    A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...

  9. POJ3648 A Simple Problem with Integers(线段树之成段更新。入门题)

    A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 53169 Acc ...

随机推荐

  1. 【ZJOI2017 Round1练习&BZOJ4767】D1T3 两双手(排列组合,DP)

    题意: 100%的数据:|Ax|,|Ay|,|Bx|,|By| <= 500, 0 <= n,Ex,Ey <= 500 思路:听说这是一道原题 只能往右或者下走一步且有禁止点的简化版 ...

  2. 学.net必学的东西 10项【不知道我能不能学这么多,!- -,光程序编辑我都累死了】

    原文发布时间为:2008-10-30 -- 来源于本人的百度文章 [由搬家工具导入] 10项.NET必学的技术2007年08月28日 星期二 14:58 1、WCF (Windows Communic ...

  3. 运行hadoop自带的计算圆周率异常

    运行hadoop2 自带的圆周率计算方法时,报错,找了半天,原来是在配置hadoop临时目录时,没有给权限,找到配置的hadoop临时目录文件夹,修改权限即可 Application applicat ...

  4. 解决WordPress安装主题/插件提示输入FTP帐号的问题

    有时比较着急想要安装一款主题或插件,却提示需要输入 FTP 帐号密码……这种情况蛮让人讨厌的,以下就是最完美的解决方法: 方法一:在 wp-config.php 文件加入代码 如果使用的是虚拟主机,可 ...

  5. React学习及实例开发(二)——用Ant Design写一个简单页面

    本文基于React v16.4.1 初学react,有理解不对的地方,欢迎批评指正^_^ 一.引入Ant Design 1.安装antd yarn add antd 2.引入 react-app-re ...

  6. Sudoku---hdu2676(数独DFS)

    http://poj.org/problem?id=2676 递归深搜 #include<stdio.h> #include<string.h> #include<alg ...

  7. html页面中拍照和上传照片那些事儿(一)

    本文为原创,转载请注明出处: cnzt  文章:cnzt-p http://www.cnblogs.com/zt-blog/p/6709037.html  一. 思路: <input type= ...

  8. C# 读自己的资源文件

    Assembly assm = this.GetType().Assembly;//Assembly.LoadFrom(程序集路径); foreach (string resName in assm. ...

  9. js中的自定义异常处理函数

    1. Can I suppress JavaScript error messages? 2. Can I set up my own JavaScript error handler? 3. Can ...

  10. 题目1011:最大连续子序列 O(n)

    题目大意:给出一系列的数字.要求你输出这些数字的最大连续和,并输出构成这个最大连续和的第一个数和最后一个数 解题思路:用一个变量维护最大连续和 假设当前这个变量小于0的话,就表示这个变量仅仅会拉低连续 ...