码迷,mamicode.com
首页 > 其他好文 > 详细

UESTC 1059 秋实大哥与小朋友(线段树 + 离散化)

时间:2016-05-04 17:19:23      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:

Description

秋实大哥以周济天下,锄强扶弱为己任,他常对天长叹:安得广厦千万间,大庇天下寒士俱欢颜。

所以今天他又在给一群小朋友发糖吃。

他让所有的小朋友排成一行,从左到右标号。在接下去的时间中,他有时会给一段区间的小朋友每人v 颗糖,有时会问第x 个小朋友手里有几颗糖。

这对于没上过学的孩子来说实在太困难了,所以你看不下去了,请你帮助小朋友回答所有的询问。

Input

第一行包含两个整数 , ,表示小朋友的个数,以及接下来你要处理的操作数。

接下来的 行,每一行表示下面两种操作之一:

0 l r v : 表示秋实大哥给[l,r]这个区间内的小朋友每人v颗糖

1 x : 表示秋实大哥想知道第x个小朋友手里现在有几颗糖

1m,v100000  , 1x1n100000000 

Output

    对于每一个1 x 操作,输出一个整数,表示第x 个小朋友手里现在的糖果数目。

Sample input and output

Sample InputSample Output
3 4
0 1 3 1
1 2
0 2 3 3
1 3
1
4

题意:

对线段树的更新查询。

注意事项:

(1)这道题的小朋友数目特别大,所以要用到一个技巧--数据的离散化(离线算法)。

所谓离线,就是在所有的输入数据已知的情况下进行的。所以需要使用一个结构体记录输入。

参考: http://www.cnblogs.com/burning-flame/p/5459107.html

(2)对内存的要求很高,所以离散化之后的映射需要用map。

附上AC代码:

#include <stdio.h>
#include <map>
#include <string.h>
#include <algorithm>
#define N 100007
using namespace std;
struct order
{
    int o;
    int a;
    int b;
    int c;
};
struct order o[N];
struct node
{
    int l;
    int r;
    long long num;
    long long lazy;
    int mid()
    {
        return (l + r) >> 1;
    }
    void update(int in)
    {
        lazy += in;
        num += (r - l + 1) * in;
    }
};
struct node bT[N * 8];
int a[N * 2];
void push_up(int i)
{
    bT[i].num = bT[i<<1].num + bT[i<<1|1].num;
}
void push_down(int i)
{
    if(bT[i].lazy)
    {
        bT[i<<1].update(bT[i].lazy);
        bT[i<<1|1].update(bT[i].lazy);
        bT[i].lazy = 0;
    }
}
void build(int L, int R, int i)
{
    bT[i].l = L;
    bT[i].r = R;
    bT[i].num = 0;
    bT[i].lazy = 0;
    if(L == R)
        return ;
    int mid = bT[i].mid();
    build(L, mid, i<<1);
    build(mid + 1, R, i<<1|1);
}
void update(int L, int R, int in, int i)
{
    if(L <= bT[i].l && R >= bT[i].r)
    {
        bT[i].update(in);
        return ;
    }
    push_down(i);
    int mid = bT[i].mid();
    if (R <= mid)
    {
        update(L, R, in, i<<1);
    }
    else if (L > mid)
    {
        update(L, R, in, i<<1|1);
    }
    else
    {
        update(L, mid, in , i<<1);
        update(mid + 1, R, in, i<<1|1);
    }
    push_up(i);
}
long long query(int x, int i)
{
    if (x == bT[i].l && x == bT[i].r)
        return bT[i].num;
    push_down(i);
    int mid = bT[i].mid();
    if (x <= mid)
    {
        long long ans = query(x, i<<1);
        push_up(i);
        return ans;
    }
    else if (x > mid)
    {
        long long ans = query(x, i<<1|1);
        push_up(i);
        return ans;
    }
}
int main()
{
    int n, m;
    map<int, int> mymap;
    scanf("%d%d", &n, &m);
    int j = 0;
    for (int i = 0; i < m; i++)
    {
        scanf("%d", &o[i].o);
        if (o[i].o)
        {
            scanf("%d", &o[i].a);
            a[j++] = o[i].a;
        }
        else
        {
            scanf("%d%d%d", &o[i].a, &o[i].b, &o[i].c);
            a[j++] = o[i].a;
            a[j++] = o[i].b;
        }
    }
    sort(a, a + j);
    int t = unique(a, a + j) - a;
    build(1, t, 1);
    for (int i = 0; i < t; i++)
        mymap[a[i]] = i + 1;
    for (int i = 0; i < m; i++)
    {
        if (o[i].o)
        {
            printf("%lld\n", query(mymap[o[i].a], 1));
        }
        else
        {
            update(mymap[o[i].a], mymap[o[i].b], o[i].c, 1);
        }
    }
    return 0;
}

 

UESTC 1059 秋实大哥与小朋友(线段树 + 离散化)

标签:

原文地址:http://www.cnblogs.com/burning-flame/p/5458991.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!