【codevs5037】线段树练习4加强版

这个题……表示不知道怎么用线段树做……空间不够用啊……只会分块了qwq

分块的思想就是把整个区间分成若干个区间,操作中,若一个小区间完全被覆盖,则把状态加入一个存储的数组,否则直接下放到每个点

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int mo=500;
char s[10];
int n,m,k,x,y,z,chu[200020],seg[404],k1[404][200020];
inline void re(int &a)//读入优化 
{
    a=0;
    bool flag=0;
    char b=getchar();
    while(b<'0'||b>'9')
    {
        if(b=='-')
            flag=1;
        b=getchar();
    }
    while(b>='0'&&b<='9')
        a=a*10+b-'0',b=getchar();
}
void add(int l,int r,int j)
{
    int fir=(l-1)/mo+1,las=(r-1)/mo;//fir是左端点所在的区间,las是右端点所在区间的左边的区间 
    if(las<fir)//说明这两个点在同一个或者相邻两个区间里 
        for(int i=l;i<=r;i++)
        {
            k1[fir][chu[i]%k]--;
            chu[i]+=j;
            k1[fir][chu[i]%k]++;
        }
    else//否则说明至少跨过三个区间 
    {
        for(int i=l;i<=fir*mo;i++)//模拟过程,开头这一段不能完全覆盖所在区间,则一个个点修改 
        {
            k1[fir][chu[i]%k]--;
            chu[i]+=j;
            k1[fir][chu[i]%k]++;
        }
        for(int i=fir+1;i<=las;i++)
            seg[i]+=j;
        for(int i=las*mo+1;i<=r;i++)//最后一段也是 
        {
            k1[las+1][chu[i]%k]--;
            chu[i]+=j;
            k1[las+1][chu[i]%k]++;
        }
    }
}
void ask(int l,int r)
{
    int fir=(l-1)/mo+1,ans=0,las=(r-1)/mo;
    if(las<fir)//思想基本同上 
    {
        for(int i=l;i<=r;i++)
        {
            if((chu[i]+seg[fir])%k==0)
                ans++;
        }
    }
    else
    {
        for(int i=l;i<=fir*mo;i++)
            if((chu[i]+seg[fir])%k==0)
                ans++;
        for(int i=fir+1;i<=las;i++)
            ans+=k1[i][(k-seg[i]%k)%k];
        for(int i=las*mo+1;i<=r;i++)
            if((chu[i]+seg[las+1])%k==0)
                ans++;
    }
    printf("%d\n",ans);
}
int main()
{
    re(n),re(m),re(k);
    for(int i=1;i<=n;i++)
        re(chu[i]),k1[(i-1)/mo+1][chu[i]%k]++;//分块初始化,我设定每500个元素分个块 
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s);
        if(s[0]=='a')
            re(x),re(y),re(z),add(x,y,z);//加值 
        else
            re(x),re(y),ask(x,y);//查询 
    }
}

 

posted @ 2017-10-29 20:30  那一抹落日的橙  阅读(170)  评论(0编辑  收藏  举报