西安段素围护澄茶树列

澄茶树列的公式弄我的好恶心呀。

#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\n",check(1,1,n,b,b));
        }
    }
    return 0;
}
posted @ 2018-06-03 21:26  Lance1ot  阅读(143)  评论(0编辑  收藏  举报