• codevs 4919 线段树练习4


    二次联通门 : codevs 4919 线段树练习4

    /*
        codevs 4919 线段树练习4
        
        线段树
        
        每个点中维护mod 7余数的个数
        
        每次利用临时数组res把原来的余数存下来 
        区间修改时把所要加的数mod7后加上当前的余数即为所求的余数
        后进行转换...
        (我知道自己说的很迷..但是自己稍微想想就好了)
         
    */
    #include <cstdio>
    
    #define Mod 7
    #define Max 100090
    
    void read (int &now)
    {
        now = 0;
        register char word = getchar ();
        bool flag = false;
        while (word < '0' || word > '9')
        {
            if (word == '-')
                flag = true;
            word = getchar ();
        }    
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
        if (flag)
            now = -now;
    }
    
    
    struct Segment_Tree
    {
        struct Segment
        {
            int l;
            int r;
            int number[7];
            int Ruri;
            int Mid;
        };
        
        int x;
        Segment tree[Max << 3];
        Segment *L, *R;
        
        void Build (int l, int r, int now)
        {
            tree[now].l = l;
            tree[now].r = r;
            if (l == r)
            {
                read (x);
                tree[now].number[x % Mod]++;
                return ;
            }
            tree[now].Mid = (l + r) >> 1;
            Build (l, tree[now].Mid, now << 1);
            Build (tree[now].Mid + 1, r, now << 1 | 1);
            for (int i = 0; i <= 6; i++)
                tree[now].number[i] = tree[now << 1].number[i] + tree[now << 1 | 1].number[i];
        }
        
        int res[7];
        
        void Change_section (int l, int r, int now, int to)
        {
            if (tree[now].l == l && tree[now].r == r)
            {
                for (int i = 0; i <= 6; i++)
                    res[i] = tree[now].number[i];
                for (int i = 0; i <= 6; i++)
                    tree[now].number[(i + to) % Mod] = res[i];
                tree[now].Ruri += to;
                return ;
            }
            if (tree[now].Ruri)
            {
                L = &tree[now << 1];
                R = &tree[now << 1 | 1];
                for (int i = 0; i <= 6; i++)
                    res[i] = L->number[i];
                for (int i = 0; i <= 6; i++)
                    L->number[(i + tree[now].Ruri) % Mod] = res[i];
                for (int i = 0; i <= 6; i++)
                    res[i] = R->number[i];
                for (int i = 0; i <= 6; i++)
                    R->number[(i + tree[now].Ruri) % Mod] = res[i];
                L->Ruri += tree[now].Ruri;
                R->Ruri += tree[now].Ruri;
                tree[now].Ruri = 0;
            }
            if (r <= tree[now].Mid)
                Change_section (l, r, now << 1, to);
            else if (l > tree[now].Mid)
                Change_section (l, r, now << 1 | 1, to);
            else
            {
                Change_section (l, tree[now].Mid, now << 1, to);
                Change_section (tree[now].Mid + 1, r, now << 1 | 1, to);  
            }  
            for (int i = 0; i <= 6; i++)
                tree[now].number[i] = tree[now << 1].number[i] + tree[now << 1 | 1].number[i];
        }
        
        int Query_section_count (int l, int r, int now)
        {
            if (tree[now].l == l && tree[now].r == r)
                return tree[now].number[0];
            if (tree[now].Ruri)
            {
                L = &tree[now << 1];
                R = &tree[now << 1 | 1];
                for (int i = 0; i <= 6; i++)
                    res[i] = L->number[i];
                for (int i = 0; i <= 6; i++)
                    L->number[(i + tree[now].Ruri) % Mod] = res[i];
                for (int i = 0; i <= 6; i++)
                    res[i] = R->number[i];
                for (int i = 0; i <= 6; i++)
                    R->number[(i + tree[now].Ruri) % Mod] = res[i];
                L->Ruri += tree[now].Ruri;
                R->Ruri += tree[now].Ruri;
                tree[now].Ruri = 0;
            }
            if (r <= tree[now].Mid)
                return Query_section_count (l, r, now << 1);
            else if (l > tree[now].Mid)
                return Query_section_count (l, r, now << 1 | 1);
            else
                return Query_section_count (l, tree[now].Mid, now << 1) + Query_section_count (tree[now].Mid + 1, r, now << 1 | 1);    
            for (int i = 0; i <= 6; i++)
                tree[now].number[i] = tree[now << 1].number[i] + tree[now << 1 | 1].number[i];
        }
    };
    
    Segment_Tree Tree;
    
    int N;
    
    int main (int argc, char *argv[])
    {
        register char type[7];
        read (N);
        Tree.Build (1, N, 1); 
        read (N);
        int x, y, z;
        while (N--) 
        {
            scanf ("%s", type);
            read (x);
            read (y);
            if (type[0] == 'c')
                printf ("%d
    ", Tree.Query_section_count (x, y, 1));
            else
            {
                read (z);
                Tree.Change_section (x, y, 1, z); 
            }
        }
        return 0;
    }
  • 相关阅读:
    第二次,营造完整的人生(上)
    御风者(二)——狼王
    我的个人博客
    FTP 协议解析
    关于 Wireshark3 中 GeoIP 的问题
    CentOS8 NextCloud 私有云存储搭建
    Windows10 临时将线程绑定至指定CPU的方法
    CentOS8 yum/dnf 配置国内源(临时)
    Cknife流量分析
    samba + OPENldap 搭建文件共享服务器
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6751599.html
Copyright © 2020-2023  润新知