hdu 3874 Necklace (树状数组+离线操作)

Necklace

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3923    Accepted Submission(s): 1292

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

Source

2011 Multi-University Training Contest 4 - Host by SDU

上一道题的弱化版本。

因为数据数组能存下,不需要离散化。

其他都差不多。

懒得写了 >_<

/*************************************************************************
    > File Name: code/hdu/3333.cpp
    > Author: 111qqz
    > Email: [email protected]
    > Created Time: 2015年08月07日 星期五 17时04分07秒
 ************************************************************************/

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
#define y0 abc111qqz
#define y1 hust111qqz
#define yn hez111qqz
#define j1 cute111qqz
#define tm crazy111qqz
#define lr dying111qqz
using namespace std;
#define REP(i, n) for (int i=0;i<int(n);++i)
typedef long long LL;
typedef unsigned long long ULL;
const int inf = 0x7fffffff;
const int N=5E4+3;
LL c[N];
LL n,m,qur;
LL ref[N];
LL pre[N];
LL ori[N];
struct Q
{
    LL val,id;
}q[N];

struct S
{
     LL x,y;
     LL id,ans;
}s[200005];

bool cmp( Q a,Q b)
{
    if (a.val<b.val) return true;
    return false;
}
bool cmp2(S a,S b)
{
    if (a.y<b.y) return true;
    return false;
}

LL lowbit ( int x)
{
    return x&(-x);
}

void update ( LL x,LL delta)
{
    for ( LL i = x ; i <= n ; i = i + lowbit(i))
    {
    c[i] = c[i] + delta;
    }
}
LL sum( LL x)
{
    LL res = 0 ;
    for ( LL i = x; i >= 1 ; i = i - lowbit(i))
    {
    res = res + c[i];
    }
    return res;
}
int main()
{
    int T;
    cin>>T;
    while (T--)
    {
    memset(ref,0,sizeof(ref));
    memset(c,0,sizeof(c));
    memset(pre,-1,sizeof(pre)); //标记上次出现位置的数组
    scanf("%lld",&n);
    for ( LL i = 1 ; i <= n ; i++)
    {
        scanf("%lld",&q[i].val);
        q[i].id  = i;
    }
    sort(q+1,q+n+1,cmp);
    LL cnt  = 0;
    for ( LL i = 1 ; i <= n ; i++ )
    {
        if (q[i].val!=q[i-1].val)
        {
        cnt++;
        }
        ref[q[i].id] = cnt;
        ori[q[i].id] = q[i].val;
    }

    scanf("%lld",&qur);
    for ( LL i = 1 ;i  <= qur; i++ )
    {
        scanf("%lld %lld",&s[i].x,&s[i].y);
        s[i].id = i;
    }
    sort(s+1,s+1+qur,cmp2);
    s[0].y = 0;
    for ( LL i = 1 ; i <= qur  ; i++)
    {
        for ( LL j = s[i-1].y+1 ; j <= s[i].y ; j++)
        {
        int tmp = ref[j];
        if (pre[tmp]==-1)
        {
            update(j,ori[j]);
        }
        else
        {
            update (j,ori[j]);
            update (pre[tmp],-ori[j]);
        }
        pre[tmp] =  j;
        }
        s[s[i].id].ans = sum(s[i].y)-sum(s[i].x-1);
    }
    for ( int i = 1 ; i <= qur ; i++ )
    {
        cout<<s[i].ans<<endl;
    }

    }

    return 0;
}
时间: 2024-10-12 09:51:50

hdu 3874 Necklace (树状数组+离线操作)的相关文章

HDU - 3874 Necklace (树状数组、离线处理)

题目链接:Necklace 题意: 给出一串珠子,每个珠子有它的value,现在给出n(n<=5e4)个珠子的value(1<=value<=1e6),现在给出m(1<=m<=2e5)个询问,每个询问给出l和r,要求[l,r]区间内所有珠子的value(如果有相同value值的珠子则只计算一次这个珠子的值). 题解: 刚开始看到这题,遇到区间求和就想到了树状数组.但是如何解决区间内相同value值只能计算一次的问题呢?看了题解后发现可以用离线化解决这个问题,我们可以先把所有的

hdu 4630 树状数组+离线操作+GCD

http://acm.hdu.edu.cn/showproblem.php?pid=4630 重新认识了树状数组. 首先要记住那个树形的图,然后+或-lowbit(i)是自己根据具体问题设定的,不要死于+或者-, 树状数组的特点: 1.+lowbit(i)可以到达包含结点i的上一层父节点    所以用于值的更改 2.-lowbit(i)可以到达不包含i所代表区间的上一层父节点  所以用于值的求和---每个不相交的段加起来 3.C[i]的含义也是根据具体问题去做设定的,但是c[i]覆盖了a[i-2

HDU Cow Sorting (树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2838 Cow Sorting Problem Description Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cow

hdu 5193 分块 树状数组 逆序对

题意: 给出n个数,a1,a2,a3,...,an,给出m个修改,每个修改往数组的某个位置后面插入一个数,或者把某个位置上的数移除.求每次修改后逆序对的个数. 限制: 1 <= n,m <= 20000; 1 <= ai <= n 思路: 插入和删除用分块来处理,块与块之间用双向链表来维护,每一块用树状数组来求小于某个数的数有多少个. 外层可以使用分块维护下标,这样添加和删除元素的时候,也很方便,直接暴力.查找权值个数时,使用树状数组比较方便.内层通过树状数组维护权值. 每次更新即

HDU 4630 No Pain No Game 树状数组+离线操作

题意:给一串数字,每次查询[L,R]中两个数的gcd的最大值. 解法:容易知道,要使取两个数让gcd最大,这两个数最好是倍数关系,所以处理出每个数的所有倍数,两两间根据倍数关系形成一条线段,值为该数.那么每次查询[L,R]之间两数gcd的最大值即为查询[L,R]中值最大的线段,离线所有的查询数据,然后按右端点坐标从小到大排序,依次往右加入即可. 这里学到了树状数组维护最大值的写法. 代码: #include <iostream> #include <cstdio> #include

hdu 3333 Turing Tree(树状数组离线操作)

Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3904    Accepted Submission(s): 1325 Problem Description After inventing Turing Tree, 3xian always felt boring when solving problems

HDU 5493 Queue 树状数组

Queue Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5493 Description N people numbered from 1 to N are waiting in a bank for service. They all stand in a queue, but the queue never moves. It is lunch time now,

hdu 4455 Substrings(树状数组+递推)

题目链接:hdu 4455 Substrings 题目大意:给定一个长度为N的序列,现在有Q次询问,每次给定一个w,表示长度,输出序列中长度为w的连续子序列 的权值和.序列的权值表示序列中不同元素的个数. 解题思路:递推,先预处理处每个位置和前面相同的数据的最短距离P.dp[i]表示说长度为i子序列的权值和,dp[i+1] = dp[i] + v - c.v为[i+1~N]中P值大于i的个数,我们可以看作将长度为i的子序列长度向后增加1,那么v则为增加长度带来 的权值增加值,c则是最后一个长度为

HDU---4417Super Mario 树状数组 离线操作

题意:给定 n个数,查询 位置L R内 小于x的数有多少个. 对于某一次查询 把所有比x小的数 ”的位置“ 都加入到树状数组中,然后sum(R)-sum(L-1)就是答案,q次查询就要离线操作了,按高度排序. #include <set> #include <map> #include <cmath> #include <ctime> #include <queue> #include <stack> #include <cct