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. Rikka with Sequence---hdu5828(区间更新与查找 线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,m个操作,操作k,l,r, k=1时 区间[l,r]每个数加x: k=2时,区间[l ...

  2. 如何控制dedecms描述的长度?

    我们都知道调用dedecms的标题长度可以用titlelen='字符数',{dede:arclist titlelen='10'},表示标题长度为10个字符,也即是5个汉字.如果想要控制描述的调用长度 ...

  3. UILabel富文本 段落格式以及UILabel添加图片

    之前文本整理有一点乱,这边重新整理一下,下面是效果图,一共两个UILabel, 富文本整理: /*NSForegroundColorAttributeName设置字体颜色,对象UIColor; NSP ...

  4. android 本地字符串存取

    存 // data 指定的文件名 SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVAT ...

  5. 开源的挖矿软件,sha256

    http://cryptomining-blog.com/tag/sha-256d-miner/ https://github.com/cbuchner1/CudaMiner/blob/master/ ...

  6. iOS UI基础-4.2应用程序管理 Xib文件使用

    Xib调整使用 1.新建xib文件 New File-->User Interface-->Empty 2.打开新建的xib文件,出现可视化窗口 (1)拖入一个UIView (不是UIVi ...

  7. python-计算器实现

    # 开发一个简单的python计算器# 实现加减乘除及括号优先级解析# 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * ...

  8. 移动端1px细线解决方案总结

    现在的PM和UI总以看app的眼光看html5, html页面要做的专业美观,而且必须很精细. 去年的时候UI就告诉我h5上的边框线太粗,把整站都给拉low了. 当时工期紧就没太在意1px粗细, 好在 ...

  9. SQL Server 2008 R2 超详细安装图文教程

    一.下载SQL Server 2008 R2安装文件 ed2k://|file|cn_sql_server_2008_r2_enterprise_x86_x64_ia64_dvd_522233.iso ...

  10. How To Join XLA_AE_HEADERS and RCV_TRANSACTIONS(子分类账到事务处理追溯)

    Applies to:   Oracle Inventory Management - Version: 12.0.6<max_ver> and later   [Release: 12 ...