hdu4267---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

Source

2012 ACM/ICPC Asia Regional Changchun Online

Recommend

liuyiding | We have carefully selected several similar problems for you: 4276 4274 4273 4272 4270

k<=10, 模k为b的情况一共是55种,所以维护55颗线段树(或者说55个延迟标记)即可,内存卡的有点紧.

/*************************************************************************
    > File Name: hdu4267.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年02月25日 星期三 18时37分15秒
 ************************************************************************/

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

const int N = 50005;
struct node
{
    int l, r;
    int sum;
    int add[55];
}tree[N << 2];

void build (int p, int l, int r)
{
    tree[p].l = l;
    tree[p].r = r;
    for (int i = 0; i < 55; ++i)
    {
        tree[p].add[i] = 0;
    }
    if (l == r)
    {
        scanf("%d", &tree[p].sum);
        return;
    }
    int mid = (l + r) >> 1;
    build (p << 1, l, mid);
    build (p << 1 | 1, mid + 1, r);
    tree[p].sum = tree[p << 1].sum + tree[p << 1 | 1].sum;
}

void pushdown (int p)
{
    int k = 1;
    int b = -1;
    for (int i = 1; i <= 55; ++i)
    {
        if (i > (2 * k + (k - 1) * (k - 2) / 2 - 1))
        {
            ++k;
            b = 0;
        }
        else
        {
            ++b;
        }
        if (tree[p].add[i - 1])
        {
            tree[p << 1].add[i - 1] += tree[p].add[i - 1];
            tree[p << 1 | 1].add[i - 1] += tree[p].add[i - 1];
            int m = (tree[p << 1].r - b) / k + 1;
            if (tree[p << 1].l - 1 - b >= 0)
            {
                m -= (tree[p << 1].l - 1 - b) / k + 1;
            }
            tree[p << 1].sum += m * tree[p].add[i - 1];
//          printf("区间[%d,%d] 模%d为%d的有%d个\n", tree[p << 1].l, tree[p << 1].r, k, b, m);
            m = (tree[p << 1 | 1].r - b) / k + 1;
            if ((tree[p << 1 | 1].l - 1 - b) >= 0)
            {
                m -= (tree[p << 1 | 1].l - 1 - b) / k + 1;
            }
            tree[p << 1 | 1].sum += m * tree[p].add[i - 1];
            tree[p].add[i - 1] = 0;
//          printf("区间[%d, %d] 模%d为%d的有%d个\n", tree[p << 1 | 1].l, tree[p << 1 | 1].r, k, b, m);
        }
    }
}

void update (int p, int l, int r, int k, int b, int c)
{
    if (l == tree[p].l && tree[p].r == r)
    {
        int m = (tree[p].r - b) / k + 1;
        if (tree[p].l - 1 - b >= 0)
        {
            m -= (tree[p].l - 1 - b) / k + 1;
        }
        tree[p].sum += m * c;
        int id = k + (k - 1) * (k - 2) / 2 + b - 1;
        tree[p].add[id] += c;
//      printf("区间[%d, %d]模%d为%d的有%d个\n", l, r, k, b, m);
        return;
    }
    pushdown (p);
    int mid = (tree[p].l + tree[p].r) >> 1;
    if (r <= mid)
    {
        update (p << 1, l, r, k, b, c);
    }
    else if (l > mid)
    {
        update (p << 1 | 1, l, r, k, b, c);
    }
    else
    {
        update (p << 1, l, mid, k, b, c);
        update (p << 1 | 1, mid + 1, r, k, b, c);
    }
    tree[p].sum = tree[p << 1].sum + tree[p << 1 | 1].sum;
}

int query (int p, int pos)
{
    if (tree[p].l == tree[p].r)
    {
        return tree[p].sum;
    }
    int mid = (tree[p].l + tree[p].r) >> 1;
    pushdown (p);
    if (pos <= mid)
    {
        return query (p << 1, pos);
    }
    else
    {
        return query (p << 1 | 1, pos);
    }
}

int main ()
{
    int n;
    while (~scanf("%d", &n))
    {
        build (1, 1, n);
        int m;
        int op, l, r, k, c;
        scanf("%d", &m);
        while (m--)
        {
            scanf("%d", &op);
            if (op == 2)
            {
                scanf("%d", &l);
                printf("%d\n", query (1, l));
            }
            else
            {
                scanf("%d%d%d%d", &l, &r, &k, &c);
                update (1, l, r, k, l % k, c);
            }
        }
    }
    return 0;
}
时间: 2024-10-06 13:43:19

hdu4267---A Simple Problem with Integers(线段树)的相关文章

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. T

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