codevs 4919 线段树练习4

Posted ZlycerQan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n", Tree.Query_section_count (x, y, 1));
        else
        {
            read (z);
            Tree.Change_section (x, y, 1, z); 
        }
    }
    return 0;
}

 

以上是关于codevs 4919 线段树练习4的主要内容,如果未能解决你的问题,请参考以下文章

codevs 4919 线段树练习4

[CodeVS4919]线段树练习4

CodeVs——T 4919 线段树练习4

codevs 4919 线段树练习4

Codevs-4919 线段树练习4(区间加上一个值并求摸个区间整除k的数的个数,线段树+数组维护)

codves 4919 线段树练习4