HDOJ 4267 A Simple Problem with Integers (线段树)

题目:

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
思路:
区间修改 单点查询
第一个操作是 对在a-b区间内的位置i 如果满足(i-a)%k==0 就把这个位置上的值加上c
式子可以等同于i%k==a%k 所以问题就转化为了右边的部分
从数据范围中可以看到k的范围很小 对k进行枚举 
k=1时 可以取的余数为0,1 
k=2时 可以取的余数为0,1 ,2
以此类推 所有可以取的结果共55种 根据取余的情况 对这一个区间内该更新哪些线段树进行纪录 然后对这一棵线段树这个区间内的所有值进行更新
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int maxn=5e4+10;
int n,m,y,a,b,k,c,op,ans;
int x[maxn];

struct node{
    int l,r,w;
    int add[55];
}tree[maxn<<2];

void build(int l,int r,int rt){
    tree[rt].l=l;
    tree[rt].r=r;
    memset(tree[rt].add,0,sizeof(tree[rt].add));
    if(l==r){
        tree[rt].w=x[l];
        return;
    }
    int mid=(l+r)/2;
    build(l,mid,rt*2);
    build(mid+1,r,rt*2+1);
    tree[rt].w=tree[rt*2].w+tree[rt*2+1].w;
}

void pushdown(int rt){
    tree[rt*2].w+=tree[rt].w;
    tree[rt*2+1].w+=tree[rt].w;
    tree[rt].w=0;
    for(int i=0;i<55;i++){
        tree[rt*2].add[i]+=tree[rt].add[i];
        tree[rt*2+1].add[i]+=tree[rt].add[i];
        tree[rt].add[i]=0;
    }
}

void update(int tmp,int rt){
    if(tree[rt].l>=a && tree[rt].r<=b){
        int index=k*(k-1)/2+tmp;
        tree[rt].add[index]+=c;
        tree[rt].w+=c;
        return;
    }
    if(tree[rt].w) pushdown(rt);
    int mid=(tree[rt].l+tree[rt].r)/2;
    if(a<=mid) update(tmp,rt*2);
    if(b>mid) update(tmp,rt*2+1);
//    tree[rt].w=tree[rt*2].w+tree[rt*2+1].w;
}

void query(int rt){
    if(tree[rt].l==y && tree[rt].r==y){
        for(int i=1;i<=10;i++){
            int index=i*(i-1)/2+y%i;
            ans+=tree[rt].add[index];
        }
        return;
    }
    if(tree[rt].w) pushdown(rt);
    int mid=(tree[rt].l+tree[rt].r)/2;
    if(y<=mid) query(rt*2);
    else query(rt*2+1);
}

int main(){
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++){
            scanf("%d",&x[i]);
        }
        build(1,n,1);
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d%d",&a,&b,&k,&c);
                update(a%k,1);
            }
            if(op==2){
                ans=0;
                scanf("%d",&y);
                query(1);
                printf("%d\n",x[y]+ans);
            }
        }
    }
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/whdsunny/p/10463770.html