BUPT Summer Journey #test8 E
来源:互联网 发布:机房网络布线方案 编辑:程序博客网 时间:2024/05/17 22:09
E. 田田的算数题 2014新生暑假个人排位赛08
时间限制 10000 ms 内存限制 65536 KB
题目描述
焦级长和田田玩算数。焦级长给田田一个数列ai,然后问田田第i项到第j项的数的和。
田田随手写了个简单的数据结构就搞定了。于是焦级长打算加大题目难度。
焦级长又添加了一个操作,即从第i项到第j项都按顺序加上一个等差数列的项
如从第2项到第4项加入一个首项为1,公差为3的等差数列即第2项+1,第3项+4,第4项+7,以此类推
于是田田写了半天又WA又T还RE了一炮,终于来求救你让你来写个程序帮他
输入格式
第一行为case数T
每个case第一行输入n,m,表示有数列长为n,有m个操作
之后n个数为ai即数列的初始数
之后m行为m个操作
第一个操作为插入
为1,l,r,x,d
1表示插入操作,l,r为数列的[l,r]会进行操作,等差数列的首项为x,公差为d
第二个操作为查询和
为2,l,r
2表示查询,l,r为求和的范围,即求al到ar的数列的和
T<=10
n,m<=10^5
ai,x<10^5,|d|<=100;
输出格式
每个查询输出一个值
输入样例
16 91 2 3 4 5 62 1 42 1 61 1 4 1 02 2 51 2 4 1 12 1 42 2 42 1 52 2 6
输出样例
10211720182529
思路:其实有了首项与公差,整个区间的和就知道了。只需要两个域记录这个区间的首项与公差即可。
代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#define maxn 1000005//#define LOCALusing namespace std;int n,m;long long a[maxn],sum[maxn<<2],sumo[maxn<<2],addv[maxn<<2],setv[maxn<<2];void build(int o,int L,int R){ //printf("L=%d R=%d\n",L,R); int lc=o<<1,rc=(o<<1)+1; addv[o]=setv[o]=0; if(L==R){sum[o]=sumo[o]=a[L];return;} int M=(L+R)>>1; build(lc,L,M); build(rc,M+1,R); sum[o]=sum[lc]+sum[rc]; //printf("0 o=%d L=%d R=%d sum=%I64d setv1=%I64d setv2=%I64d\n",o,L,R,sumv[o],setv1[o],setv2[o]);}void maintain(int o,int L,int R){ int lc=o<<1,rc=(o<<1)+1; sum[o]=0; if(L==R)sum[o]=sumo[o]; if(L<R)sum[o]=sum[lc]+sum[rc]; sum[o]+=addv[o]*(R-L+1); sum[o]+=(R-L+1)*(R-L)/2*setv[o];}void update(int o,int L,int R,int l,int r,long long v,long long d){ //printf("1 o=%d L=%d R=%d l=%d r=%d v=%I64d d=%I64d\n",o,L,R,l,r,v,d); int lc=o<<1,rc=(o<<1)+1; if(l<=L&&R<=r) { addv[o]+=(v+(L-l)*d); setv[o]+=d; } else { int M=(L+R)>>1; if(l<=M)update(lc,L,M,l,r,v,d); if(M<r)update(rc,M+1,R,l,r,v,d); } maintain(o,L,R); //printf("2 o=%d L=%d R=%d l=%d r=%d v=%I64d d=%I64d\n",o,L,R,l,r,v,d); //printf("sum=%I64d addv=%I64d setv=%I64d\n",sum[o],addv[o],setv[o]);}long long query(int o,int L,int R,int l,int r,long long add,long long set){ long long ret=0; int lc=o<<1,rc=(o<<1)+1; //printf("3 o=%d L=%d R=%d l=%d r=%d add=%I64d set=%I64d\n",o,L,R,l,r,add,set); if(l<=L&&R<=r) { //printf("sumo=%I64d\n",sum[o]); ret+=(sum[o]+add*(R-L+1)+(R-L)*(R-L+1)/2*set); } else { int M=(L+R)>>1; if(l<=M)ret+=query(lc,L,M,l,r,add+addv[o],set+setv[o]); if(M<r) { //printf("3.5 o=%d L=%d R=%d l=%d r=%d add=%I64d set=%I64d\n",o,L,R,l,r,add,set); //printf("3.5 o=%d M+1=%d R=%d l=%d r=%d add=%I64d set=%I64d\n",o,M+1,R,l,r,add,set); //printf("3.5 %I64d %I64d\n",addv[o],setv[o]); ret+=query(rc,M+1,R,l,r,add+addv[o]+(M-L+1)*(set+setv[o]),set+setv[o]); } } //printf("4 o=%d L=%d R=%d l=%d r=%d add=%I64d set=%I64d\n",o,L,R,l,r,add,set); //printf("4 ret=%I64d\n",ret); return ret;}int main(){ #ifdef LOCAL freopen("input.txt","r",stdin); #endif // LOCAL int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); build(1,1,n); long long kind,l,r,x,d; for(int i=1;i<=m;i++) { scanf("%lld",&kind); if(kind==1) { scanf("%lld%lld%lld%lld",&l,&r,&x,&d); update(1,1,n,l,r,x,d); } if(kind==2) { scanf("%lld%lld",&l,&r); printf("%lld\n",query(1,1,n,l,r,0,0)); } } } return 0;}
0 0
- BUPT Summer Journey #test8 E
- BUPT Summer Journey #test8 A
- BUPT Summer Journey #test8 B
- BUPT Summer Journey #test8 C
- BUPT Summer Journey #test8 D
- BUPT Summer Journey #test1 E
- BUPT Summer Journey #test2 E
- BUPT Summer Journey #test3 E
- BUPT Summer Journey #test4 E
- BUPT Summer Journey #test5 E
- BUPT Summer Journey #test6 E
- BUPT Summer Journey #test7 E
- BUPT Summer Journey #test11 E
- BUPT Summer Journey #test1 A
- BUPT Summer Journey #test1 B
- BUPT Summer Journey #test1 C
- BUPT Summer Journey #test1 D
- BUPT Summer Journey #test2 A
- Metasploit数据库问题汇总
- js验证码
- 学英语尽量不要从背词汇表开始
- 【设计模式】桥接模式
- ios--检测用户截屏, 并获取所截图片
- BUPT Summer Journey #test8 E
- 11g的延迟段功能
- 值—结果参数详解
- using namespace std
- AFNetworking2.5使用
- 在cocos2d-js-v3.0 中使用cocostudio UI的正确方式
- Windows 7下DotProject环境搭建及其安装
- 基于 OpenFlow 实现网络虚拟化
- HTML5播放器MediaElement.js用法