HDU 3874 Necklace (线段树单点更新+区间查询+离线操作)

Problem Description

Mery has a beautiful necklace. The necklace is made up of N magic balls. Each ball has a beautiful value. The balls with the same beautiful value look the same, so if two or more balls have the same beautiful value, we just count
it once. We define the beautiful value of some interval [x,y] as F(x,y). F(x,y) is calculated as the sum of the beautiful value from the xth ball to the yth ball and the same value is ONLY COUNTED ONCE. For example, if the necklace is 1 1 1 2 3 1, we have
F(1,3)=1, F(2,4)=3, F(2,6)=6.

Now Mery thinks the necklace is too long. She plans to take some continuous part of the necklace to build a new one. She wants to know each of the beautiful value of M continuous parts of the necklace. She will give you M intervals [L,R] (1<=L<=R<=N) and you
must tell her F(L,R) of them.

Input

The first line is T(T<=10), representing the number of test cases.

For each case, the first line is a number N,1 <=N <=50000, indicating the number of the magic balls. The second line contains N non-negative integer numbers not greater 1000000, representing the beautiful value of the N balls. The third line has a number
M, 1 <=M <=200000, meaning the nunber of the queries. Each of the next M lines contains L and R, the query.

Output

For each query, output a line contains an integer number, representing the result of the query.

Sample Input

2
6
1 2 3 4 3 5
3
1 2
3 5
2 6
6
1 1 1 2 3 5
3
1 1
2 4
3 5

Sample Output

3
7
14
1
3
6

按区间的右端点排序,离线查询各个区间,在查询之前 删除扫到的点的前一个位置出现的点。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <iostream>
#include <string>
#include <map>
#include <stack>
#define lson o<<1, l, m
#define rson o<<1|1, m+1, r
using namespace std;
typedef long long LL;
const int maxn = 50005;
const int MAX = 0x3f3f3f3f;
const int mod = 1000000007;
int t, n, m, A, B, in[maxn], last[maxn], pre[1000005];  //last记录每个点的前一个相同的点的位置,不存在记录为-1.
LL sum[maxn<<2], ans[200005];
struct C {
    int l, r, num;
}a[200005];
bool cmp (C x, C y) {
    return x.r < y.r;
}

void up(int o) {
    sum[o] = sum[o<<1] + sum[o<<1|1];
}

void build(int o, int l, int r) {
    if(l == r) sum[o] = in[l];
    else {
        int m = (l+r) >> 1;
        build(lson);
        build(rson);
        up(o);
    }
}

void update(int o, int l, int r) {
    if(l == r) {
        sum[o] = 0;
        return ;
    }
    int m = (l+r) >> 1;
    if(A <= m) update(lson);
    else update(rson);
    up(o);
}

LL query(int o, int l, int r) {
    if(A <= l && r <= B) return sum[o];
    int m = (l+r) >> 1;
    LL res = 0;
    if(A <= m) res += query(lson);
    if(m < B ) res += query(rson);
    return res;
}

void Ini() {
    memset(pre, -1, sizeof(pre));
    memset(last, -1, sizeof(last));
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &in[i]);
        if(pre[ in[i] ] != -1) {
            last[i] = pre[ in[i] ];
            pre[ in[i] ] = i;
        } else pre[ in[i] ] = i;
    }
}

int main()
{
    scanf("%d", &t); while (t--) {
        Ini();
        scanf("%d", &m);
        for(int i = 1; i <= m; i++) {
            scanf("%d%d", &a[i].l, &a[i].r);
            a[i].num = i;
        }
        sort(a+1, a+m+1, cmp);
        build(1, 1, n);
        int fr = 1;
        for(int i =1; i <= m; i++) {
            for(int j = fr; j <= a[i].r; j++)
                if(last[j] != -1) {
                    A = last[j];
                    update(1, 1, n);
                }
            A = a[i].l;
            B = a[i].r;
            ans[ a[i].num ] = query(1, 1, n);
            fr = a[i].r+1;
        }
        for(int i = 1; i <= m; i++) printf("%I64d\n", ans[i]);
    }
    return 0;
}



HDU 3874 Necklace (线段树单点更新+区间查询+离线操作)

时间: 2024-09-28 15:47:48

HDU 3874 Necklace (线段树单点更新+区间查询+离线操作)的相关文章

HDU 1166(线段树单点更新)

HDU 1166 题意:1-n个堡垒,人数在不断变化,多次查询 l-r人数和: 思路:线段树的单点更新: #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<algorithm> #include<cmath> #include<map> #include<vector> #include<queu

POJ 3264 Balanced Lineup (线段树单点更新 区间查询)

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 36820   Accepted: 17244 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh

hihoCoder week19 RMQ问题再临-线段树 单点更新 区间查询

单点更新 区间查询 #include <bits/stdc++.h> using namespace std; #define m ((l+r)/2) #define ls (rt<<1) #define rs (rt<<1|1) const int N = 2e6+10; int s[N], tr[N]; void build(int rt,int l,int r) { if(l == r) { tr[rt] = s[l]; return ; } build(ls,

hdu 5480 Conturbatio 线段树 单点更新,区间查询最小值

Conturbatio Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5480 Description There are many rook on a chessboard, a rook can attack the row and column it belongs, including its own place. There are also many quer

HDU1166(线段树单点更新区间查询)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 62483    Accepted Submission(s): 26386 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就

CDOJ 1073 线段树 单点更新+区间查询 水题

H - 秋实大哥与线段树 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%lld & %llu Submit Status Practice UESTC 1073 Appoint description:  System Crawler  (2016-04-24) Description “学习本无底,前进莫徬徨.” 秋实大哥对一旁玩手机的学弟说道. 秋实大哥是一个爱学习的人,今天他刚刚学习了线段树这个数据结构. 为

HDU 2795 Billboard(线段树,单点更新)

D - Billboard Crawling in process... Crawling failed Time Limit:8000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2795 Appoint description: bupt_admin_13 (2015-07-28) System Crawler (2015-08-18) Description

HDU 2795 Billboard (线段树 单点更新 区间求最大值)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题意:有一块h*w 的广告版,有n块1*w[i]的广告,就着放广告尽量在顶上,尽量先放左边的原则,问在第几行能把广告放下,如果放不下,就打印-1: 思路:我们可以根据每一行建树,每一个子叶表示每一行的容量,而节点存放子节点的最大值,然后从最顶到底,快速查找能存放下广告的一行. 总之还是简单的线段树问题,难点在于抽象模型. #include <iostream> #include <cs

HDU 3308 LCIS (线段树&#183;单点更新&#183;区间合并)

题意  给你一个数组  有更新值和查询两种操作  对于每次查询  输出对应区间的最长连续递增子序列的长度 基础的线段树区间合并  线段树维护三个值  对应区间的LCIS长度(lcis)  对应区间以左端点为起点的LCIS长度(lle)  对应区间以右端点为终点的LCIS长度(lri)  然后用val存储数组对应位置的值  当val[mid + 1] > val[mid] 的时候就要进行区间合并操作了 #include <cstdio> #include <algorithm>