Poj3468-A Simple Problem with Integers(伸展树练练手)
Description
You have N integers, A1, A2, ... , 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 A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000. Each of the next Q lines represents an operation. "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000. "Q a b" means querying the sum of Aa, Aa+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
- 题意: 给出N个数,有两种操作
Q a b 查询[a,b]区间的和
C a b c [a,b]区间所有值加上c- 解析:成段更新问题,线段树已经可以做,我试着用伸展树做做。
- 代码:
- //这题用线段树就可以做了,拿来用伸展树练练手
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<algorithm>
- using namespace std;
- typedef long long LL;
- const int maxn=;
- int A[maxn],cnt; //A数组保存数,cnt是节点标号,我是用数组模拟的
- struct treap
- {
- treap* son[]; //左右儿子
- int s;
- LL v,add,sum;
- treap(){ s=v=add=sum=; son[]=son[]=NULL; }
- treap(LL nv);
- int rk(){ return son[]->s+; } //排名,第几个数
- int cmp(int k) //比较,如果相等返回-1,小于返回0,大于1
- {
- if(k==rk()) return -;
- return k<rk()?:;
- }
- void Set(LL d)
- {
- v+=d;
- add+=d;
- sum+=d*s;
- }
- void pushup()
- {
- s=son[]->s+son[]->s+;
- sum=son[]->sum+son[]->sum+v;
- }
- void pushdown() //处理懒惰标记
- {
- if(add!=)
- {
- son[]->Set(add);
- son[]->Set(add);
- add=;
- }
- }
- }null,tr[maxn];
- treap::treap(LL nv)
- {
- sum=v=nv;
- s=;
- add=;
- son[]=son[]=&null;
- }
- treap* NewNode(LL x)
- {
- tr[cnt]=treap(x);
- return tr+cnt++;
- }
- struct splaytree
- {
- int Size;
- treap* root;
- splaytree(){ Size=; root=&null; }
- void Rotate(treap* &t,int d) //翻转操作
- {
- t->pushdown();
- treap* p=t->son[d^];
- p->pushdown();
- t->son[d^]=p->son[d];
- p->son[d]=t;
- t->pushup();
- t=p;
- t->pushup();
- }
- void Splay(treap* &t,int k) //将第k大的节点伸展到根
- {
- t->pushdown();
- int d=t->cmp(k);
- if(d!=-)
- {
- if(d) Splay(t->son[d],k- t->rk());
- else Splay(t->son[d],k);
- Rotate(t,d^);
- }
- }
- void Build(treap* &t,int le,int ri) //将N个数建成一棵树
- {
- if(le>ri) return;
- int mid=(le+ri)/;
- t=NewNode(A[mid]);
- Build(t->son[],le,mid-);
- Build(t->son[],mid+,ri);
- t->pushup();
- }
- LL Query(treap* &t,int x,int y)
- {
- LL ret=;
- Splay(t,y);
- ret+=t->son[]->sum+t->v;
- if(x>)
- {
- Splay(t,x-);
- ret-=t->son[]->sum+t->v;
- }
- return ret;
- }
- void Add(treap* &t,int x,int y,int add)
- {
- Splay(t,y);
- t->v+=add; t->sum+=add*y;
- t->son[]->Set(add);
- if(x>)
- {
- Splay(t,x-);
- t->v-=add; t->sum-=add*(x-);
- t->son[]->Set(-add);
- }
- }
- };
- int main()
- {
- int N,Q;
- while(scanf("%d%d",&N,&Q)!=EOF)
- {
- for(int i=;i<=N;i++) scanf("%d",&A[i]);
- splaytree spt;
- cnt=;
- spt.Build(spt.root,,N);
- int x,y,d;
- char op[];
- while(Q--)
- {
- scanf("%s",op);
- if(op[]=='Q')
- {
- scanf("%d%d",&x,&y);
- printf("%lld\n",spt.Query(spt.root,x,y));
- }
- else
- {
- scanf("%d%d%d",&x,&y,&d);
- spt.Add(spt.root,x,y,d);
- }
- }
- }
- return ;
- }
Poj3468-A Simple Problem with Integers(伸展树练练手)的更多相关文章
- poj3468 A Simple Problem with Integers (线段树区间最大值)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 92127 ...
- poj3468 A Simple Problem with Integers (树状数组做法)
题目传送门 A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 1 ...
- POJ3468 A Simple Problem with Integers —— 线段树 区间修改
题目链接:https://vjudge.net/problem/POJ-3468 You have N integers, A1, A2, ... , AN. You need to deal wit ...
- POJ 3468 A Simple Problem with Integers (伸展树区间更新求和操作 , 模板)
伸展数最基本操作的模板,区间求和,区间更新.为了方便理解,特定附上一自己搞的搓图 这是样例中的数据输入后建成的树,其中的1,2是加入的边界顶点,数字代表节点编号,我们如果要对一段区间[l, r]进行操 ...
- POJ3468 A Simple Problem with Integers(线段树延时标记)
题目地址http://poj.org/problem?id=3468 题目大意很简单,有两个操作,一个 Q a, b 查询区间[a, b]的和 C a, b, c让区间[a, b] 的每一个数+c 第 ...
- poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)
转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...
- 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和
poj3468 A Simple Problem with Integers 题意:O(-1) 思路:O(-1) 线段树功能:update:成段增减 query:区间求和 Sample Input 1 ...
- 2018 ACMICPC上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节)
2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节) 链接:https://ac.nowcoder.co ...
- POJ3468 A Simple Problem with Integers 【段树】+【成段更新】
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 57666 ...
随机推荐
- Ext中图片上传预览的问题,困扰了好几天终于解决了,记录下
{ columnWidth:.50, xtype:'textfield', style:"padding-top:5px", name:'goodsMainPhoto', id:' ...
- Java常见内存溢出异常分析(OutOfMemoryError)
原文转载自:http://my.oschina.net/sunchp/blog/369412 1.背景知识 1).JVM体系结构 2).JVM运行时数据区 JVM内存结构的相关可以参考: http:/ ...
- 【转】USB协议架构及驱动架构
1. USB协议 1.1 USB主机系统 在USB主机系统中,通过根集线器与外部USB从机设备相连的处理芯片,称为USB主机控制器.USB主机控制器包含硬件.软件和固件一部分. 1.2 USB设备系统 ...
- dom4j解析接口使用SOAP传递的xml
xml 文件的格式类型: <?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope ...
- mini2440裸机试炼之——DMA直接存取 实现Uart(串口)通信
这个仅仅能作为自己初步了解MDA的开门篇 实现功能: 将字符串数据通过DMA0通道传递给UTXH0,然后在终端 显示.传输数据完后.DMA0产生中断,beep声, LED亮. DMA基本知识 计算机系 ...
- Javascript高级程序设计读书笔记(第二章)
第二章 在HTML中使用Javascript 2.1<script>元素 延迟脚本(defer = "defer")表明脚本在执行时不会影响页面的构造,脚本会被延迟到 ...
- ios面试汇总
http://www.360doc.com/content/15/0707/01/26281448_483232245.shtml
- js中的for-of循环遍历数组
遍历数组要怎么做,可能你首先想到的会是for循环,当然for循环在JavaScript 刚萌生的时候就出现了,想到它也是理所当然的 var a=[[1,2],[3,4],5] for(var i=0; ...
- deflate树与deflate编码
关于deflate树,能搜到的资料非常少,这个概念来自gzip的压缩算法,是由huffman树转变过来的.这里简单记录下deflate树的生成过程以及deflate编码. 假设以5 8 9 10 14 ...
- (原)ubuntu16重装显卡驱动后,torch中的问题
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6030232.html 参考网址: https://github.com/torch/cutorch/i ...