HDU 4267 - A Simple Problem with Integers 树状数组区间修改

73 篇文章 21 订阅
56 篇文章 0 订阅


解法请看http://blog.csdn.net/diannaok/article/details/7959423

挺有收获的。以前虽然会区间修改,但不熟练。没想到可以通过k来解决问题。


A Simple Problem with Integers

Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2907    Accepted Submission(s): 938


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
 


//
//  4267.cpp
//  ACM_HDU
//
//  Created by ipqhjjybj on 13-9-7.
//  Copyright (c) 2013年 ipqhjjybj. All rights reserved.
//

#include<cstdio>
#include <iostream>
#include <cstring>
#define lowbit(x) ((x)&(-x))

int a[50050][11][11];
int s[50050];
int n,q;
void Update(int mod,int k,int pos,int add){
    while(pos>0){
        a[pos][k][mod]+=add;
        pos-=lowbit(pos);
    }
}
int Query(int pos,int num){
    int i,sum=0;
    while(pos<=n){
        for(i=1;i<=10;i++)
            sum+=a[pos][i][num%i];
        pos+=lowbit(pos);
    }
    return sum;
}
int main(){
    while(scanf("%d",&n)!=EOF){
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
            scanf("%d",s+i);
        scanf("%d",&q);
        int cas,a,b,k,c;
        while(q--){
            scanf("%d",&cas);
            switch(cas){
                case 2:
                    scanf("%d",&a);
                    printf("%d\n",Query(a,a)+s[a]);
                break;
                case 1:
                    scanf("%d %d %d %d",&a,&b,&k,&c);
                    Update(a%k,k,b,c);
                    Update(a%k,k,a-1,-c);
                break;
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值