luogu3368树状数组模板2
题目链接:https://www.luogu.org/problemnew/show/P3368
题意:与模板1不同的是这题的操作是树状数组并不在行的区间更新和单点查找,如果按照模板1那样写肯定会T。但这题题目是树状数组模板,所以肯定还是能用树状数组来做的,我用a数组保存原数组,tr数组表示树状数组。
进行区间更新update时,只需要将组成这个区间的几个大管辖节点加这个数(类似于线段树中的懒操作)。
查询的时候,依层找自己的上级,然后加上自己上级的值就行了。因为在这里,上级的值就相当于懒操作的值。
具体可以找组数据模拟一下,就懂了,这样做的复杂度同树状数组一样,但tr数组已经不是定义上的树状数组了,我们只是借用了树状数组这一数据结构。
AC代码:
#include<cstdio> #include<cctype> using namespace std; inline int read(){ int x=0,f=0;char c=0; while(!isdigit(c)){f|=c=='-';c=getchar();} while(isdigit(c)){x=(x<<3)+(x<<1)+(c^48);c=getchar();} return f?-x:x; } int a[500005],tr[500005],n,m; int lowbit(int x){ return x&(-x); } void update(int x,int k){ while(x>0){ tr[x]+=k; x-=lowbit(x); } } int query(int x){ int ans=0; while(x<=n){ ans+=tr[x]; x+=lowbit(x); } return ans; } int main(){ n=read(),m=read(); for(int i=1;i<=n;++i) a[i]=read(); while(m--){ int op=read(); if(op==1){ int x=read(),y=read(),k=read(); update(y,k); update(x-1,-k); } else{ int x=read(); printf("%d\n",a[x]+query(x)); } } return 0; }
朋友们,无论这个世界变得怎样,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。