HDU4267

題意:第一行一個n,表示數的個數,下面一行n個數是初始數值,然後一行一個數m代表m個詢問數,1 a b k c代表a到b區間內每隔k個數加c;2 a代表詢問a出的值。樹狀數組可解,如果是對a到b區間內的所有數加c用樹狀數組很好解決,對於此題,由於是a、b間每隔k個數才進行更新,k的值在10之內,取餘數也比較少可以對對應每個k建一棵樹,對應的每個餘數進行更新,數組定義就變成了C[N][11][11];具體代碼:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int N = 50010;

int c[N][11][11], numb[N];

int lowbit(int x)
{
    return x&(-x);
}

void update(int x, int k, int add, int mod)
{
    while(x > 0)
    {
        c[x][k][mod] += add;
        x -= lowbit(x);
    }
}

int sum(int x, int a)
{
    int s = 0;
    while(x < N)
    {
        for(int i=1; i<11; ++i)
            s += c[x][i][a%i];
        x += lowbit(x);
    }

    return s;
}

int main()
{
    int n, m, key;

    while(~scanf("%d", &n))
    {
        for(int i=1; i<=n; ++i)
            scanf("%d", &numb[i]);
        memset(c, 0, sizeof(c));

        scanf("%d", &m);
        while(m--)
        {
            scanf("%d", &key);
            if(key == 1)
            {
                int a, b, k, add;
                scanf("%d%d%d%d", &a, &b, &k, &add);
                update(a-1, k, -add, a%k);
                update(b, k, add, a%k);
            }
            else
            {
                int a;
                scanf("%d", &a);
                printf("%d\n", numb[a] + sum(a, a));
            }
        }
    }

    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章