HDU4267 A Simple Problem with Integers 线段树/树状数组

HDU4267 A Simple Problem with Integers  线段树/树状数组

2012长春网络赛A题

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

树状数组:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

const int maxn=50005;

int N,Q;
int val[maxn];
int add[maxn][11][10];
int op,a,b,k,c;

inline int lowbit(int x){ return x & -x;}
inline void _add(int pos, int val, int k, int x){
    for(; pos <= N; pos += lowbit(pos)) add[pos][k][x] += val;
}

inline void update(int l, int r, int val, int k, int x){
    _add(l, val, k, x); _add(r+1, -val, k, x);
}

int _sum(int pos, int k, int x){
    int res = 0;
    for(; pos >= 1; pos -= lowbit(pos)) res += add[pos][k][x];
    return res;
}

int query(int p)
{
    for(int k=1;k<11;k++){
        for(int x=0;x<k;x++){
            if(p%k==x%k){
                int tmp=_sum(p,k,x);
                val[p]+=tmp;
                update(p,p,-tmp,k,x);
            }
        }
    }
    return val[p];
}

int main()
{
    freopen("in.txt","r",stdin);
    while(~scanf("%d",&N)){
        memset(add,0,sizeof(add));
        for(int i=1;i<=N;i++) scanf("%d",&val[i]);
        scanf("%d",&Q);
        while(Q--){
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d%d",&a,&b,&k,&c);
                update(a,b,c,k,a%k);
            }
            else{
                scanf("%d",&a);
                printf("%d\n",query(a));
            }
        }
    }
    return 0;
}

线段树:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

const int maxn=50005;

int N;
struct SegTree
{
    int val;
    int add[55];
};
SegTree T[maxn*3];
int op,a,b,k,c;
int Q;
int ID[11][11];

void Init()
{
    int id=0;
    for(int k=1;k<11;k++){
        for(int x=0;x<k;x++){
            ID[k][x]=id++;
        }
    }
}

void build(int l,int r,int rt)
{
    T[rt].val=0;
    memset(T[rt].add,0,sizeof(T[rt].add));
    if(l==r){
        scanf("%d",&T[rt].val);
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}

void push_down(int rt)
{
    for(int k=1;k<11;k++){
        for(int x=0;x<k;x++){
            int id=ID[k][x];
            T[rt<<1].add[id]+=T[rt].add[id];
            T[rt<<1|1].add[id]+=T[rt].add[id];
            T[rt].add[id]=0;
        }
    }
}

void update(int L,int R,int c,int id,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        T[rt].add[id]+=c;
        return;
    }
    push_down(rt);
    int m=(l+r)>>1;
    if(L<=m) update(L,R,c,id,lson);
    if(R>m) update(L,R,c,id,rson);
}

int query(int p,int l,int r,int rt)
{
    if(l==r){
        for(int k=1;k<11;k++){
            for(int x=0;x<k;x++){
                int id=ID[k][x];
                if(l%k==x%k) T[rt].val+=T[rt].add[id];
                T[rt].add[id]=0;
            }
        }
        return T[rt].val;
    }
    push_down(rt);
    int m=(l+r)>>1;
    if(p<=m) return query(p,lson);
    else return query(p,rson);
}

int main()
{
    freopen("in.txt","r",stdin);
    while(~scanf("%d",&N)){
        Init();
        build(1,N,1);
        scanf("%d",&Q);
        while(Q--){
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d%d",&a,&b,&k,&c);
                int id=ID[k][a%k];
                update(a,b,c,id,1,N,1);
            }
            else{
                scanf("%d",&a);
                printf("%d\n",query(a,1,N,1));
            }
        }

    }
    return 0;
}

时间: 2024-10-27 10:11:51

HDU4267 A Simple Problem with Integers 线段树/树状数组的相关文章

POJ 3468 A Simple Problem with Integers(线段树区间更新)

题目地址:POJ 3468 打了个篮球回来果然神经有点冲动..无脑的狂交了8次WA..居然是更新的时候把r-l写成了l-r... 这题就是区间更新裸题.区间更新就是加一个lazy标记,延迟标记,只有向下查询的时候才将lazy标记向下更新.其他的均按线段树的来就行. 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <math.h> #include <stac

POJ3468_A Simple Problem with Integers(线段树/成段更新)

解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio> #define LL long long #define int_now int l,int r,int root using namespace std; LL sum[500000],lazy[500000]; void push_up(int root,int l,int r) { sum[ro

【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each

POJ3468__A Simple Problem with Integers (线段树)

本文出自blog.csdn.net/svitter --我大C++的指针岂是尔等能够简单领悟! 题意 给N个节点,标号A1~An,然后有Q个操作,操作分为Q i j,查询i,j间的区间和.C i j k,i到j个数字,每个数字增加k,并且输出. 输入输出分析 给N,Q,然后跟操作.注意判断Q,C使用scanf("%s"). 测试数据: Sample Input 10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4 Samp

POJ-3468 A Simple Problem with Integers(线段树)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 94899   Accepted: 29568 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解

A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of

POJ 3468 A Simple Problem with Integers (线段树区域更新)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 62431   Accepted: 19141 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

[POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]

A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of

poj3468 A Simple Problem with Integers 线段树区间更新

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 97722   Accepted: 30543 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of