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 <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <iostream>
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<R)
        update(mod,L,R,k,c,mid+1,r,root<<1|1);
}

int main()
{
    int cnt=0;
    for(int i=1;i<11;i++)///分组
    {
        for(int j=0;j<i;j++)
            b[i][j]=cnt++;
    }
    int n,m;
    while(~scanf("%d",&n))
    {
        build(1,n,1);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
        }
        scanf("%d",&m);
        while(m--)
        {
            int x;
            scanf("%d",&x);
            if(x==1)
            {
                int u,v,k,c;
                scanf("%d%d%d%d",&u,&v,&k,&c);
                update(u%k,u,v,k,c,1,n,1);
            }
            else
            {
                int pos;
                scanf("%d",&pos);
                printf("%d\n",query(pos,1,n,1)+num[pos]);
            }
        }
    }
    return 0;
}


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分组线段树)