• codevs 4919 线段树练习4


    时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
    题目描述 Description

    给你N个数,有两种操作

    1:给区间[a,b]内的所有数都增加X

    2:询问区间[a,b]能被7整除的个数

    输入描述 Input Description

    第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是add,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是count,表示统计区间[a,b]能被7整除的个数

    输出描述 Output Description

    对于每个询问输出一行一个答案

    样例输入 Sample Input

       

    3 
    2 3 4
    6
    count 1 3
    count 1 2
    add 1 3 2
    count 1 3
    add 1 3 3
    count 1 3
    样例输出 Sample Output

    0

    0

    0

    1

    数据范围及提示 Data Size & Hint

    10%:1<N<=10,1<Q<=10

    30%:1<N<=10000,1<Q<=10000

    100%:1<N<=100000,1<Q<=100000

    用节点的余数来统计被整除的个数 

    修改节点的值时 建立临时数组存取统计的个数 

    然后交换过来

    屠龙宝刀点击就送

    #include <cstdio>
    #define Max 100000
    struct node
    {
        int l,r,flag,num[8];
    }tr[Max<<2|1];
    int n,m,a;
    void up(int k)
    {
        for(int i=0;i<=6;i++)
        tr[k].num[i]=tr[k<<1].num[i]+tr[k<<1|1].num[i];
    }
    void read(int &x)
    {
        x=0;bool f=1;
        char ch=getchar();
        while(ch>'9'||ch<'0')
        {
            if(ch=='-') f=0;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+(int)ch-48;
            ch=getchar();
        }
        x=f?x:(~x)+1;
    }
    void build(int k,int l,int r)
    {
        tr[k].l=l;tr[k].r=r;
        if(l==r)
        {
            read(a);
            tr[k].num[a%7]++;
            return;
        }
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        up(k);
    }
    void pushdown(int k)
    {
        if(tr[k].l==tr[k].r) return;
        int tmp[8];
        tr[k<<1].flag+=tr[k].flag;
        tr[k<<1|1].flag+=tr[k].flag;
        for(int i=0;i<=6;i++) tmp[i]=tr[k<<1].num[i];
        for(int i=0;i<=6;i++)
        {
            tr[k<<1].num[(i+tr[k].flag)%7]=tmp[i];
            tmp[i]=tr[k<<1|1].num[i];
        }
        for(int i=0;i<=6;i++) tr[k<<1|1].num[(i+tr[k].flag)%7]=tmp[i];
        tr[k].flag=0;
    }
    int section_query(int k,int l,int r)
    {
        if(tr[k].l==l&&tr[k].r==r) return tr[k].num[0];
        if(tr[k].flag) pushdown(k);
        int mid=(tr[k].l+tr[k].r)>>1;
        if(l>mid) return section_query(k<<1|1,l,r);
        else if(r<=mid) return section_query(k<<1,l,r);
        else return section_query(k<<1,l,mid)+section_query(k<<1|1,mid+1,r);
    }
    void section_change(int k,int l,int r,int v)
    {
        if(tr[k].l==l&&tr[k].r==r)
        {
            int tmp[8];
            for(int i=0;i<=6;i++) tmp[i]=tr[k].num[i];
            for(int i=0;i<=6;i++) tr[k].num[(i+v)%7]=tmp[i];
            tr[k].flag+=v;
            return;
        }
        if(tr[k].flag) pushdown(k);
        int mid=(tr[k].l+tr[k].r)>>1;
        if(l>mid) section_change(k<<1|1,l,r,v);
        else if(r<=mid) section_change(k<<1,l,r,v);
        else section_change(k<<1,l,mid,v),section_change(k<<1|1,mid+1,r,v);
        up(k);
    }
    int main()
    {
        read(n);
        build(1,1,n);
        read(m);
        char str[11];
        for(int x,y,z;m--;)
        {
            scanf("%s",str+1);
            if(str[1]=='c')
            {
                read(x);read(y);
                printf("%d
    ",section_query(1,x,y));
            }
            else if(str[1]=='a')
            {
                read(x);read(y);read(z);
                section_change(1,x,y,z);
            }
        }
        return 0;
    }
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    [错误处理]UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)
    [已解决]使用 apt-get update 命令提示 ...中被配置了多次
    linux各种版本查看方法
    [Pandas技巧] 如何把pandas dataframe对象或series对象转换成list
    linux下终止相关操作
    [错误处理]Vim卡死,无法输入是怎么回事?是不是按了Ctrl+S
    批量修改文件名称方法
    pycharm配置 自动运行指定脚本
    pip安装超时,更换国内镜像源安装
    命令行特殊字符名字转义
  • 原文地址:https://www.cnblogs.com/ruojisun/p/6753765.html
Copyright © 2020-2023  润新知