https://scut.online/p/337

这个东西是个阶梯状的。那么可以考虑存两棵树,一棵树是阶梯的,另一棵树的平的,随便一减就是需要的阶梯。

优化之后貌似速度比树状数组还惊人。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; inline int read() {
int x=0;
int f=0;
char c;
do {
c=getchar();
if(c=='-')
f=1;
} while(c<'0'||c>'9');
do {
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
} while(c>='0'&&c<='9');
return f?-x:x;
} inline void _write(int x) {
if(x>9)
_write(x/10);
putchar(x%10+'0');
} inline void write(int x) {
if(x<0) {
putchar('-');
x=-x;
}
_write(x);
putchar('\n');
} void TestCase(int ti); int main() {
#ifdef Yinku
freopen("Yinku.in","r",stdin);
//freopen("Yinku.out","w",stdout);
#endif // Yinku
int T=1;
for(int ti=1; ti<=T; ti++)
TestCase(ti);
} /*--- ---*/ const int MAXM=100000;
int a[MAXM+5];
int st[(MAXM<<2)+5];
int st2[(MAXM<<2)+5]; const int mod=1000000007; inline int add(const int &a,const int &b){
int res=a+b;
return res>=mod?res-mod:res;
} inline int sub(const int &a,const int &b){
int res=a-b;
return res<0?res+mod:res;
} inline int mul(const int &a,const int &b){
ll res=1ll*a*b;
return res>=mod?res%mod:res;
} inline void push_up(int o) {
st[o]=add(st[o<<1],st[o<<1|1]);
st2[o]=add(st2[o<<1],st2[o<<1|1]);
} void build(int o,int l,int r) {
if(l==r){
st[o]=a[l];
st2[o]=mul(l,a[l]);
}
else {
int m=(l+r)>>1;
build(o<<1,l,m);
build(o<<1|1,m+1,r);
push_up(o);
}
} void update(int o,int l,int r,int x,int v) {
if(l==r) {
st[o]=v;
st2[o]=mul(x,v);
return;
} else {
int m=(l+r)>>1;
if(x<=m)
update(o<<1,l,m,x,v);
else if(x>=m+1)
update(o<<1|1,m+1,r,x,v);
push_up(o);
}
} int query1(int o,int l,int r,int a,int b) {
if(a<=l&&r<=b) {
return st[o];
} else {
int m=(l+r)>>1;
int ans=0;
if(a<=m)
ans=query1(o<<1,l,m,a,b);
if(b>=m+1)
ans=add(ans,query1(o<<1|1,m+1,r,a,b));
return ans;
}
} int query2(int o,int l,int r,int a,int b) {
if(a<=l&&r<=b) {
return st2[o];
} else {
int m=(l+r)>>1;
int ans=0;
if(a<=m)
ans=query2(o<<1,l,m,a,b);
if(b>=m+1)
ans=add(ans,query2(o<<1|1,m+1,r,a,b));
return ans;
}
} inline void TestCase(int ti) {
int n,m;
while(~scanf("%d",&n)) {
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
build(1,1,n);
scanf("%d",&m);
for(int i=1; i<=m; i++) {
char a[2];
int b,c;
scanf("%s%d%d",a,&b,&c);
if(a[0]=='Q') {
printf("%d\n",sub(query2(1,1,n,b,c),mul(b-1,query1(1,1,n,b,c))));
} else {
update(1,1,n,b,c);
}
}
}
}

这个树状数组就不太好懂了,不过空间是线段树的1/4,速度是其两倍。

单点改值就把差值update上去就可以了。然后记得把原始值也顺手改了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; inline int read() {
int x=0;
int f=0;
char c;
do {
c=getchar();
if(c=='-')
f=1;
} while(c<'0'||c>'9');
do {
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
} while(c>='0'&&c<='9');
return f?-x:x;
} inline void _write(int x) {
if(x>9)
_write(x/10);
putchar(x%10+'0');
} inline void write(int x) {
if(x<0) {
putchar('-');
x=-x;
}
_write(x);
putchar('\n');
} void TestCase(int ti); int main() {
#ifdef Yinku
freopen("Yinku.in","r",stdin);
//freopen("Yinku.out","w",stdout);
#endif // Yinku
int T=1;
for(int ti=1; ti<=T; ti++)
TestCase(ti);
} /*--- ---*/ const int MAXM=100000;
int a[MAXM+5];
int bit[MAXM+5];
int bit2[MAXM+5]; int n; const int mod=1000000007; inline int add(const int &a,const int &b) {
int res=a+b;
return res>=mod?res-mod:res;
} inline int sub(const int &a,const int &b) {
int res=a-b;
return res<0?res+mod:res;
} inline int mul(const int &a,const int &b) {
ll res=1ll*a*b;
return res>=mod?res%mod:res;
} inline int sum(int x,int bit[]) {
int res=0;
while(x) {
res=add(res,bit[x]);
x-=x&-x;
}
return res;
} inline void update(int x,int v,int bit[]) {
while(x<=n) {
bit[x]=add(bit[x],v);
x+=x&-x;
}
} inline int range_sum(int x,int y,int bit[]) {
return sub(sum(y,bit),sum(x-1,bit));
} inline void TestCase(int ti) {
int m;
while(~scanf("%d",&n)) {
memset(bit,0,sizeof(bit));
memset(bit2,0,sizeof(bit2));
for(int i=1; i<=n; i++) {
scanf("%d",&a[i]);
update(i,a[i],bit);
update(i,mul(i,a[i]),bit2);
}
scanf("%d",&m);
for(int i=1; i<=m; i++) {
char s[2];
int b,c;
scanf("%s%d%d",s,&b,&c);
if(s[0]=='Q') {
printf("%d\n",sub(range_sum(b,c,bit2),mul(b-1,range_sum(b,c,bit))));
} else {
int delta=sub(c,a[b]);
update(b,delta,bit);
update(b,mul(b,delta),bit2);
a[b]=c;
}
}
}
}

SCUT - 337 - 岩殿居蟹 - 线段树 - 树状数组的更多相关文章

  1. CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)

    The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...

  2. [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  3. HDU 1556 线段树或树状数组,插段求点

    1.HDU 1556  Color the ball   区间更新,单点查询 2.题意:n个气球,每次给(a,b)区间的气球涂一次色,问最后每个气球各涂了几次. (1)树状数组 总结:树状数组是一个查 ...

  4. HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树

    HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...

  5. 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings

    谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...

  6. HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)

    题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS     Memory Limit: 32768 K Description The inve ...

  7. POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树

    题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...

  8. Turing Tree_线段树&树状数组

    Problem Description After inventing Turing Tree, 3xian always felt boring when solving problems abou ...

  9. HDU 1166 敌兵布阵 (数状数组,或线段树)

    题意:... 析:可以直接用数状数组进行模拟,也可以用线段树. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&quo ...

随机推荐

  1. vim乱码的解决

    解决vim文件乱码,打开文件乱码,菜单,提示信息乱码: 有四个跟字符编码方式有关的选项,encoding.fileencoding.fileencodings.termencoding 在linux中 ...

  2. 代码题(14)— 合并有序链表、数组、合并K个排序链表

    1.21. 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出 ...

  3. Execution Context(EC) in ECMAScript

    参考资料 执行环境,作用域理解 深入理解JavaScript系列(2):揭秘命名函数表达式 深入理解JavaScript系列(12):变量对象(Variable Object) 深入理解JavaScr ...

  4. hihocoder -1283 hiho密码(水题)

      时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho根据最近在密码学课上学习到的知识,开发出了一款hiho密码,这款密码的秘钥是这样生成的:对于一种有N个字母的语言 ...

  5. codeforces 652B B. z-sort(水题)

    题目链接: B. z-sort time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  6. ffmpeg avpicture_fill的一些使用

    标签: ffmpegavpicture_fill 2013-05-17 10:03 4713人阅读 评论(1) 收藏 举报  分类: ffmpeg(3)  这个FFMPEG我没找到详细的中文教程,只有 ...

  7. 树套树Day1线段树套平衡树bzoj3196

    您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查 ...

  8. Bootstrap日期/日历插件Datepicker 时间加标记

    由于工作需要,项目中使用了Bootstrap日期/日历插件Datepicker,根据需求需要在其中添加日期标记,实现效果图如下: 特此记录此次解决方案: 1.首先分析了功能的DOM元素(如下图),可以 ...

  9. 白话算法(6) 散列表(Hash Table) 从理论到实用(下)

    [澈丹,我想要个钻戒.][小北,等等吧,等我再修行两年,你把我烧了,舍利子比钻戒值钱.] ——自扯自蛋 无论开发一个程序还是谈一场恋爱,都差不多要经历这么4个阶段: 1)从零开始.没有束缚的轻松感.似 ...

  10. BZOJ2809:[APIO2012]dispatching

    浅谈左偏树:https://www.cnblogs.com/AKMer/p/10246635.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php? ...