澄茶树列的公式弄我的好恶心呀。
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
long long val;//和
long long fir;//首项
long long pub;//公差
};
node t[400100];
long long base[400100];
void push_up(int root)
{
t[root].val=t[root<<1].val+t[root<<1|1].val;
return ;//处理和
}
void push_down(int root,int l,int m,int r)
{
t[root<<1].fir+=t[root].fir;//处理首项,将等差数列拆分
t[root<<1|1].fir+=(t[root].fir+t[root].pub*(m-l+1));
t[root<<1].pub+=t[root].pub;//处理公差
t[root<<1|1].pub+=t[root].pub;
t[root<<1].val+=t[root].fir*(m-l+1)+t[root].pub*(m-l)*(m-l+1)/2;
t[root<<1|1].val+=t[root].fir*(r-m)+t[root].pub*(m-l+1+r-l)*(r-m)/2;
t[root].fir=0;//置空
t[root].pub=0;
return ;
}//下放标记
void build(int root,int l,int r)
{
if(l==r)
{
t[root].val=base[l];
return ;
}
int mid=(l+r)>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
push_up(root);
return ;
}//很简单的建树
void change(int root,int l,int r,int al,int ar,long long num,long long k)
{
if(l>=al&&r<=ar)
{
t[root].val+=(num*(r-l+1)+k*(r-l+1)*(r-l)/2);
t[root].fir+=num;
t[root].pub+=k;
return ;
}
int mid=(l+r)>>1;
push_down(root,l,mid,r);
if(mid>=al&&mid+1<=ar)
{
long long chg=num+k*(mid-max(l,al)+1);
change(root<<1,l,mid,al,ar,num,k);
change(root<<1|1,mid+1,r,al,ar,chg,k);
push_up(root);
return ;
}
if(mid>=ar)
change(root<<1,l,mid,al,ar,num,k);
if(mid+1<=al)
change(root<<1|1,mid+1,r,al,ar,num,k);
push_up(root);
return ;
}
long long check(int root,int l,int r,int al,int ar)
{
if(l>ar||r<al)
return 0;
if(l>=al&&r<=ar)
return t[root].val;
int mid=(l+r)>>1;
push_down(root,l,mid,r);
long long res=check(root<<1,l,mid,al,ar)+check(root<<1|1,mid+1,r,al,ar);
return res;//很简单的查询
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&base[i]);
build(1,1,n);
int a,b,c;
long long d,e;
for(int i=1;i<=m;i++)
{
scanf("%d",&a);
if(a==1)
{
scanf("%d%d%lld%lld",&b,&c,&d,&e);
change(1,1,n,b,c,d,e);
}
else
{
scanf("%d",&b);
printf("%lld
",check(1,1,n,b,b));
}
}
return 0;
}