[COGS2632] [HZOI 2016] 数列操作d
来源:互联网 发布:梦想网络 编辑:程序博客网 时间:2024/04/28 20:24
题目
一个长度为
支持两种操作,
最终答案对
题解
这是我偶然翻到学弟学妹们出的一道题,于是就做了做。
首先这道题肯定能用线段树做,随便打打标记。
但是这道题也可以用树状数组做,更快,但是思想应该比线段树复杂些,就当是锻炼一下了。
下面是树状数组做法。
便于理解,将题目中的
树状数组求区间
首先考虑只有一次插入
- 当
L1≤x≤R1 时,Sum(x)=∑i=1L1−10+∑i=L1x(i−L1)⋅k1=(x−L1)(x−L1+1)k1/2
令K=k/2 Sum(x)=(x−L1)(x−L1+1)K1=x2(K1)+x(1−2L1)K1+(L21−L1)K1
注意到K1,(1−2L1)K1,(L21−L1)K1 都与x 无关,对[L1,R1] 中每个Sum(x) 都不变,于是可以单点插入这三种值,记他们为A1,B1,C1 ,分别插入到树状数组A,B,C 中,分别代表二次项系数、一次项系数和常数项,则Sum(x)=A1x2+B1x+C1 。 - 当
x>R1 时,这条线段不存在了,那么在R1+1 处插入−A1,−B1,−C1 ,但这条线段对Sum(x) 有贡献,需要将他的贡献K1(R1−L1)(R1−L1+1) 插入到常数项的R1+1 位置。
现在考虑多条线段的情形,容易发现可以线性叠加,求出
代码
/// by ztx/// blog.csdn.net/hzoi_ztx#include <bits/stdc++.h>#define Rep(i,l,r) for(i=(l);i<=(r);i++)#define rep(i,l,r) for(i=(l);i< (r);i++)#define Rev(i,r,l) for(i=(r);i>=(l);i--)#define rev(i,r,l) for(i=(r);i> (l);i--)#define Each(i,v) for(i=v.begin();i!=v.end();i++)#define r(x) read(x)typedef long long ll ;typedef double lf ;int CH , NEG ;template <typename TP>inline void read(TP& ret) { ret = NEG = 0 ; while (CH=getchar() , CH<'!') ; if (CH == '-') NEG = true , CH = getchar() ; while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ; if (NEG) ret = -ret ;}#define kN 300010LL#define mod 1000000007LL#define half 500000004LL#define lb (p&(-p))int n, A[kN], B[kN], C[kN];inline void Delta(int p,int w,int c[kN]) { for (;p<=n;p+=lb) (c[p] += w) %= mod;}inline int Sum(int p,int c[kN]) { int ret = 0; for (;p;p-=lb) (ret += c[p]) %= mod; return ret;}inline int Sum(int p) { return (1LL*Sum(p,A)*p%mod*p%mod+1LL*Sum(p,B)*p%mod+1LL*Sum(p,C)%mod)%mod;}inline void Modify(int L,int R,ll x) { x = x*half%mod; Delta(L,x,A); Delta(L,x*(1LL-2*L)%mod,B); Delta(L,x*L%mod*(L-1)%mod,C); Delta(R+1,-x,A); Delta(R+1,-x*(1LL-2*L)%mod,B); Delta(R+1,(-x*L%mod*(L-1)%mod + x*(R-L)%mod*(R-L+1)%mod)%mod,C);}inline void Query(int L,int R) { printf("%lld\n", ((1LL*Sum(R)-Sum(L-1))%mod+mod)%mod);}int main() { freopen("segment.in","r",stdin); freopen("segment.out","w",stdout); int m, L, R, x; r(n), r(m); while (m --> 0) { r(L); if (L) r(L), r(R), r(x), Modify(L,R,x); else r(L), r(R), Query(L,R); } END: getchar(), getchar(); return 0;}
阅读全文
0 0
- [COGS2632] [HZOI 2016] 数列操作d
- cogs2632. [HZOI 2016]数列操作d
- 最小生成树 HZOI 2016公路修建
- 拓展lucas [HZOI 2016]艾米利亚的魔法
- 数列操作
- 数列操作
- 数列操作
- [COGS2443] [HZOI 2016]MC之旅:逃离基友
- COGS 2479. [HZOI 2016]偏序 双重CDQ分治+树状数组
- bitset [HZOI 2016]动物城的鸳鸯蛋传说
- 【HZOI】 排队
- 【HZOI】 Path
- 【HZOI】 赏花
- 【HZOI】Maze
- 【HZOI】 Tree
- oj-14-D-数列
- 线段树--数列操作
- [树状数组]操作数列
- CodeForces 822B Crossword solving
- Android Toast基础与原理
- 楼宇中开放系统的LonWorks解决方案
- 字符串——拼接最小字典
- mina框架中对iosession的封装
- [COGS2632] [HZOI 2016] 数列操作d
- reportlab教程1--第一个pdf生成
- Ubuntu 基础操作命令
- Linux 常用基本命令 -ls
- HDU1043:Eight(A*+康托)
- POJ100
- Android源码分析之理解Binder通信机制
- Java并发编程:Callable、Future和FutureTask
- WebService查询美食Listview显示