cogs 2633. [HZOI 2016] 数列操作e

2633. [HZOI 2016] 数列操作e

★★★☆   输入文件:rneaty.in   输出文件:rneaty.out   简单对比
时间限制:1 s   内存限制:128 MB

【题目描述】

一个长度为n的序列,一开始序列数的权值都是0,有m次操作

支持两种操作,

1 L R x,给区间[L,R]内,第一个数加x,第二个数加22x,第三个数加32x...第R-L+1个数加(RL+1)2x

2 L R 查询区间[L,R]内的权值和

每次询问的答案对264取模

【输入格式】

第一行两个数n,m,表示序列长度和操作次数

接下来m行,每行描述一个操作,有如下两种情况:

1 L R x,给区间[L,R]内,第一个数加x,第二个数加22x,第三个数加32x...第R-L+1个数加(RL+1)2x

2 L R 查询区间[L,R]内的权值和

【输出格式】

为了减少输出,你只需要输出所有答案对264取膜之后的异或和。

【样例输入】

5 5

1 3 4 1

2 1 5

2 2 2

1 3 3 1

1 2 4 1

【样例输出】

5

【提示】

对于10%的数据 n,m<=2000

对于30%的数据 n,m<=10000

对于100%的数据,n,m<=100000,1<=L<=R<=n,0<=x<=109

【来源】

一只名字很长的蒟蒻

线段树标记永久化QAQ

这一道题的方法就是先把题目中的那个式子拆开

就可以最终拆分成这样:i^2*x + i*2(1-L)*x +(L-1)^2*x

然后针对每一项 我们打一个lz标记

同时要先预处理出一些东东

比如第一项可以预处理出i^2

第二项可以预处理出i*2*(1-L)

第三项可以预处理出(L-1)^2//其实这个不需要预处理 

然后我们把式子拆分开来后就简单多了

这里还有几个补充的知识点

1.unsigned long long 是自动对2^64取模

2.一定要注意类型 防止爆intQAQ 比如那个i^2   就要i*1ull*i才行 (否则就30分 )

代码如下

♪(^∇^*)

#include<bits/stdc++.h>
#define maxn 100005
#define LL unsigned long long
#define mid (l+r>>1)
using namespace std;
int n,m;
int RT;
int cnt;//标记 下标 
int ls[maxn<<1],rs[maxn<<1];
LL lz0[maxn<<1],lz1[maxn<<1],lz2[maxn<<1];
LL sum[maxn<<1];
LL s1[maxn],s2[maxn];
void Build(int &rt,int l,int r)
{
    if(!rt) 
        rt=++cnt;
    if(l==r)
        return;
    Build(ls[rt],l,mid);
    Build(rs[rt],mid+1,r);
}
LL ans;
void Add(int rt,int l,int r,int s,int t,LL x2,LL x1,LL x0)
{
    if(s>r||t<l)
        return;
    if(s<=l&&r<=t)
    {
        lz2[rt]+=x2;
        lz1[rt]+=x1;
        lz0[rt]+=x0;
        sum[rt]=sum[ls[rt]]+sum[rs[rt]]+lz2[rt]*(s2[r]-s2[l-1])+lz1[rt]*(s1[r]-s1[l-1])+lz0[rt]*(r-l+1);
        return;
    }
    Add(ls[rt],l,mid,s,t,x2,x1,x0);
    Add(rs[rt],mid+1,r,s,t,x2,x1,x0);
    sum[rt]=sum[ls[rt]]+sum[rs[rt]]+lz2[rt]*(s2[r]-s2[l-1])+lz1[rt]*(s1[r]-s1[l-1])+lz0[rt]*(r-l+1);
    return;
}
LL Sum(int rt,int l,int r,int s,int t)
{
    if(s>r||t<l)
        return 0;
    if(s<=l&&r<=t)    return sum[rt];
    int ll=max(l,s);
    int rr=min(r,t);
    return Sum(ls[rt],l,mid,s,t)+Sum(rs[rt],mid+1,r,s,t)+lz2[rt]*(s2[rr]-s2[ll-1])+lz1[rt]*(s1[rr]-s1[ll-1])+lz0[rt]*(rr-ll+1);
}
int main()
{
    freopen("rneaty.in","r",stdin);
    freopen("rneaty.out","w",stdout);
    scanf("%d%d",&n,&m);
    Build(RT,1,n);
    for(int i=1;i<=n;i++)
    {
        s1[i]=s1[i-1]+i;
        s2[i]=s2[i-1]+i*1ull*i;
    }
    while(m--)
    {
        int opt,L,R;
        scanf("%d%d%d",&opt,&L,&R);
        if(opt==1)
        {
            LL x;
            scanf("%llu",&x);
            //i^2*x + i*2(1-L)*x +(L-1)^2*x 
            //1^2 + 2^2 +3^2 +..+n^2   =n*(n+1)*(2n+1)/6
            Add(1,1,n,L,R,x,x*2*(1ull-L),(L-1)*x*(L-1)) ;
        }
        else
            ans^=Sum(1,1,n,L,R);
    }
    printf("%llu
",ans);
    return 0;
}
快点开瞅瞅♪(^∇^*)

 

原文地址:https://www.cnblogs.com/Tidoblogs/p/11344147.html