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

261 2 3 4 3 531 23 52 661 1 1 2 3 531 12 43 5
 
Sample Output

3714136


思路:

树状数组对于维护数组有很大优势,复杂度O(M*lgN)。树状数组讲解

我们用树状数组维护题中的数组,但是他要求不能计算重复的点,这里用了一个很巧妙的方法:先将问题按照最右边界从小到大排序,然后对这个数组去重,最后我们记录当前问题的答案,再做下一个问题,这样我们就能保证每个问题都去重并且没有删去元素。

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<queue>
#include<cmath>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<iostream>
#include<algorithm>
#include<sstream>
#define ll long long
const int N=50005;
const int MAX=200005;
const int INF=1e9;
using namespace std;
map<int,int> mp;
int num[N],n;
ll ans[MAX],tree[N];
struct node{
int l,r,no;
}que[MAX];
int cmp(node a,node b){
if(a.r<b.r) return 1;
return 0;
} //树状数组操作-start
int lowbit(int x){
return x&(-x);
}
void update(int x,int val){ //更新
for(int i=x;i<=n;i+=lowbit(i)){
tree[i]+=val;
}
}
ll sum(int x){ //计算1~x的和
ll count=0;
for(int i=x;i>=1;i-=lowbit(i)){
count+=tree[i];
}
return count;
}
//树状数组操作-end int main(){
int T,m;
cin>>T;
while(T--){
memset(tree,0,sizeof(tree));
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
cin>>m;
for(int i=1;i<=m;i++){
scanf("%d%d",&que[i].l,&que[i].r);
que[i].no=i; //表示这是第几个问题
}
sort(que+1,que+m+1,cmp);
mp.clear(); //map存储num[i]的最新位置
int pos=1;
for(int i=1;i<=m;i++){
while(pos<=que[i].r){
if(mp[num[pos]]!=0){ //如果重复出现
update(mp[num[pos]],-num[pos]); //删掉之前那个
}
mp[num[pos]]=pos;
update(pos,num[pos]);
pos++;
}
ans[que[i].no]=sum(que[i].r)-sum(que[i].l-1);
}
for(int i=1;i<=m;i++){
printf("%lld\n",ans[i]);
}
}
return 0;
}

hdu 3874(树状数组)题解的更多相关文章

  1. hdu 3874 树状数组

    思路:和求区间内有多少个不同的数一样,只不过改下权值. #include<iostream> #include<cstdio> #include<algorithm> ...

  2. hdu 4638 树状数组 区间内连续区间的个数(尽可能长)

    Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  3. hdu 4777 树状数组+合数分解

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  4. HDU 1934 树状数组 也可以用线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=1394 或者是我自己挂的专题http://acm.hust.edu.cn/vjudge/contest/view. ...

  5. 【模板】HDU 1541 树状数组

    http://acm.hdu.edu.cn/showproblem.php?pid=1541 题意:给你一堆点,每个点右一个level,为其右下方所有点的数量之和,求各个level包含的点数. 题解: ...

  6. HDU 2852 (树状数组+无序第K小)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2852 题目大意:操作①:往盒子里放一个数.操作②:从盒子里扔掉一个数.操作③:查询盒子里大于a的第K小 ...

  7. HDU 4911 (树状数组+逆序数)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4911 题目大意:最多可以交换K次,就最小逆序对数 解题思路: 逆序数定理,当逆序对数大于0时,若ak ...

  8. hdu 5792(树状数组,容斥) World is Exploding

    hdu 5792 要找的无非就是一个上升的仅有两个的序列和一个下降的仅有两个的序列,按照容斥的思想,肯定就是所有的上升的乘以所有的下降的,然后再减去重复的情况. 先用树状数组求出lx[i](在第 i ...

  9. HDU 5775 树状数组

    Bubble Sort Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  10. 2018 CCPC网络赛 1010 hdu 6447 ( 树状数组优化dp)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6447 思路:很容易推得dp转移公式:dp[i][j] = max(dp[i][j-1],dp[i-1][j ...

随机推荐

  1. TortoiseGit密钥的配置(转)

    add by zhj:说到密钥,就不得不提非对称加密.目前使用最广泛的非对称加密算法是rsa,它是美国三位科学家于1977年发明的. 一对密钥对有两个密钥,其中一个为私钥,一个为公钥,两者没有什么区别 ...

  2. startuml 2.6注册

    参考:http://bbs.chinapyg.com/thread-79022-1-1.html 各平台版本均适用,本文更改的为Mac版本.​ 1,打开对应 mac版本的安装包位置,在对应目录/App ...

  3. sql优化实例(用左连接)

    改为 也就是说用左连接代替where条件,这样的话效率会提高很多.

  4. python中执行shell命令行read结果

    +++++++++++++++++++++++++++++ python执行shell命令1 os.system 可以返回运行shell命令状态,同时会在终端输出运行结果 例如 ipython中运行如 ...

  5. vertx打成jar包发布工程,访问静态页面

    1:添加pom依赖,配置打包插件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="htt ...

  6. [django]Django model中数据批量导入bulk_create()

    参考: https://www.cnblogs.com/ccorz/p/Django-model-zhong-shu-ju-pi-liang-dao-rubulkcreat.html import o ...

  7. selenium webdriver处理浏览器Cookie

    有时候我们需要验证浏览器中是否存在某个cookie,因为基于真实的cookie 的测试是无法通过白盒和集成测试完成的.WebDriver 提供了操作Cookie 的相关方法可以读取.添加和删除cook ...

  8. java的poi技术读取Excel数据

    这篇blog主要是讲述java中poi读取excel,而excel的版本包括:2003-2007和2010两个版本, 即excel的后缀名为:xls和xlsx. 读取excel和MySQL相关: ja ...

  9. C语言标准函数源代码

    http://ftp.gnu.org/gnu/glibc/ 最新glibc-2.27.tar.gz 直接解压就可以

  10. [转]VS中展开和折叠代码

    VS2005代码编辑器的展开和折叠代码确实很方便和实用.以下是展开代码和折叠代码所用到的快捷键,很常用: Ctrl + M + O: 折叠所有方法 Ctrl + M + M: 折叠或者展开当前方法 C ...