hdu4267分组线段树

http://acm.hdu.edu.cn/showproblem.php?pid=4267



Problem Description
Let A1, A2, ... , AN be N elements. You need to deal with two kinds of operations. One type of operation is to add a given number to a few numbers in a given interval. The other is to query the value of some element.
 

Input
There are a lot of test cases. 
The first line contains an integer N. (1 <= N <= 50000)
The second line contains N numbers which are the initial values of A1, A2, ... , AN. (-10,000,000 <= the initial value of Ai <= 10,000,000)
The third line contains an integer Q. (1 <= Q <= 50000)
Each of the following Q lines represents an operation.
"1 a b k c" means adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0. (1 <= a <= b <= N, 1 <= k <= 10, -1,000 <= c <= 1,000)
"2 a" means querying the value of Aa. (1 <= a <= N)
 

Output
For each test case, output several lines to answer all query operations.
 

Sample Input

4 1 1 1 1 14 2 1 2 2 2 3 2 4 1 2 3 1 2 2 1 2 2 2 3 2 4 1 1 4 2 1 2 1 2 2 2 3 2 4
 

Sample Output

1 1 1 1 1 3 3 1 2 3 4 1
 
/***
hdu4267分组线段树
题目大意:对于给定区间[a,b]的数(i-a)%k==0加上c,最后单点查询。
解题思路:分组为[a,b]区间内除k余m的分为一组。这样按组来更新就好了。
*/
#include 
#include 
#include 
#include 
#include 
using namespace std;
const int maxn=50010;

int tree[maxn*4][55];
int flag[maxn*4];
int b[11][11],num[maxn];

void build(int l,int r,int root)
{
    flag[root]=0;
    for(int i=0;i<55;i++)
    {
        tree[root][i]=0;
    }
    if(l==r)return;
    int mid=(l+r)/2;
    build(l,mid,root<<1);
    build(mid+1,r,root<<1|1);
}

void push_down(int root)
{
    if(flag[root])
    {
        flag[root<<1|1]=flag[root<<1]=flag[root];
        flag[root]=false;
        for(int i=0;i<55;i++)
        {
            tree[root<<1][i]+=tree[root][i];
            tree[root<<1|1][i]+=tree[root][i];
            tree[root][i]=0;
        }
    }
}

int query(int pos,int l,int r,int root)
{
    if(l==r)
    {
        int ret=0;
        for(int i=1;i<=10;i++)
        {
            ret+=tree[root][b[i][pos%i]];
        }
        return ret;
    }
    push_down(root);
    int m=(l+r)/2;
    if(pos<=m)
        return query(pos,l,m,root<<1);
    else
        return query(pos,m+1,r,root<<1|1);
}

void update(int mod,int L,int R,int k,int c,int l,int r,int root)
{
    if(L<=l&&r<=R)
    {
       /// printf("*\n");
        tree[root][b[k][mod]]+=c;
        flag[root]=true;
        return;
    }
    int mid=(l+r)>>1;
    if(L<=mid)
        update(mod,L,R,k,c,l,mid,root<<1);
    if(mid


Problem Description
Let A1, A2, ... , AN be N elements. You need to deal with two kinds of operations. One type of operation is to add a given number to a few numbers in a given interval. The other is to query the value of some element.
 

Input
There are a lot of test cases. 
The first line contains an integer N. (1 <= N <= 50000)
The second line contains N numbers which are the initial values of A1, A2, ... , AN. (-10,000,000 <= the initial value of Ai <= 10,000,000)
The third line contains an integer Q. (1 <= Q <= 50000)
Each of the following Q lines represents an operation.
"1 a b k c" means adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0. (1 <= a <= b <= N, 1 <= k <= 10, -1,000 <= c <= 1,000)
"2 a" means querying the value of Aa. (1 <= a <= N)
 

Output
For each test case, output several lines to answer all query operations.
 

Sample Input

4 1 1 1 1 14 2 1 2 2 2 3 2 4 1 2 3 1 2 2 1 2 2 2 3 2 4 1 1 4 2 1 2 1 2 2 2 3 2 4
 

Sample Output

1 1 1 1 1 3 3 1 2 3 4 1
 

你可能感兴趣的:(线段树&&数组数组,数据结构)