差分+树状数组【p4868】Preprefix sum
Description
前缀和(prefix sum)Si=∑ik=1ai。
前前缀和(preprefix sum) 则把S_i作为原序列再进行前缀和。记再次求得前缀和第i个是SS_i
给一个长度n的序列a_1, a_2, \cdots, a_n有两种操作:
Modify i x
:把a_i改成x;Query i
:查询SS_iInput
第一行给出两个整数N,M。分别表示序列长度和操作个数
接下来一行有N个数,即给定的序列a1,a2,....an
接下来M行,每行对应一个操作,格式见题目描述
Output
对于每个询问操作,输出一行,表示所询问的SSi的值。
显然,这是差分+树状数组
题目中给定的a_i就是我们的差分数组。
不会差分的小伙汁,来这里
安利很好的写树状数组的博客.
然后推一下式子.
如果我们修改差分数组a_i,显然,S_i会变化.
S_i=S_{i-1}+a_i
现在变成了
S_i=S_{i-1}+x
那么差值就变成了x-a_i
那么,我们就add(i,x-a[i]),不要忘了最后将a_i变为x
代码
#include<cstdio>
#include<algorithm>
#include<iostream>
#define int long long
#define R register
using namespace std;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,m,last,t1[1000008],t2[1000008],a[1000008];
#define lowbit(x) x&-x
inline void add(int pos,int x)
{
for(R int i=pos;i<=n;i+=lowbit(i))
t1[i]+=x,t2[i]+=pos*x;
}
inline int query(int pos)
{
R int res=0;
for(R int i=pos;i;i-=lowbit(i))
res+=t1[i]*(pos+1)-t2[i];
return res;
}
char opt[8];
signed main()
{
in(n),in(m);
for(R int i=1,x;i<=n;i++)
{
in(a[i]);
add(i,a[i]);
}
for(R int i=1,x,y;i<=m;i++)
{
scanf("%s",opt+1);
if(opt[1]=='Q')
{
in(x);
printf("%lld\n",query(x));
}
else
{
in(x),in(y);
add(x,y-a[x]);
a[x]=y;
}
}
}
除特殊声明外,本博客作品均由顾z创作。
未经博主允许,不得转载
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· DeepSeek V3 两周使用总结
· 回顾我的软件开发经历(1)
· C#使用yield关键字提升迭代性能与效率
· 低成本高可用方案!Linux系统下SQL Server数据库镜像配置全流程详解
· 4. 使用sql查询excel内容