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. CodeForces 444C 节点更新求变化值的和

    http://vjudge.net/problem/viewProblem.action?id=51622 题目大意: 给定一列n个数字,最初赋予值1到n 两个操作:1.将区间[l,r]内的数改为x, ...

  2. HDU3572:Task Schedule【最大流】

    上了一天课 心塞塞的 果然像刘老师那么说 如果你有挂科+4级没过 那基本上是WF队 题目大意:有时间补吧 思路:给每个任务向每个时间点连边容量为1 每个时间点向汇点连边 容量为机器的个数 源点向每个任 ...

  3. MTK andorid从底层到上层添加驱动

    1 [编写linux驱动程序] 1.1 一.编写驱动核心程序 1.2 二.配置Kconfig 1.3 三.配置Makefile 1.4 四.配置系统的autoconfig 1.5 五.编译 2 [编写 ...

  4. JS变量写到HTML页面中并修改变量值(前台处理数据序号问题)

    有时候我们在前台需要对序号进行处理,我们需要将JS变量写到页面中进行显示. 第一种方式:后台处理 第二种方式:JS中定义全局变量,然后进行显示,可以书写一个JS函数对不同的需要进行不同的替换,也就可以 ...

  5. 实现浏览器兼容的innerText

    今天学习到了FF不支持innerText,而IE.chrome.Safari.opera均支持innerText. 为了各个浏览器能兼容innerText,必须对js做一次封装. 为啥能实现兼容呢?原 ...

  6. 2017CodeM初赛A场

    A.最长树链(loj6159) 分析: 对于每个质因数,取出所有是它倍数的点组成一个树,然后找最长路径 每个数操作次数是其质因数的个数 所以总的复杂度不超过O(nlogA) B.二分图染色(loj61 ...

  7. HDTVI,HDCVI

    HDTVI是海康的同轴高清标准,HDCVI是大华的同轴高清标准,二者互相不兼容.

  8. TUN/TAP区别

    在计算机网络中,TUN与TAP是操作系统内核中的虚拟网络设备.不同于普通靠硬件网路板卡实现的设备,这些虚拟的网络设备全部用软件实现,并向运行于操作系统上的软件提供与硬件的网络设备完全相同的功能. TA ...

  9. java 实现打印当前月份的日历

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcTc0NTQwMTk5MA==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  10. angular $resource 的 get请求 和 post请求

    1.语法: $resource(url,[paramDefaults],[actions],options); 详解: (1)url:一个参数化的url模板 (2)paramDefaults:url参 ...