HDU 3874 Necklace (树状数组 | 线段树 的离线处理)
Necklace
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2083 Accepted Submission(s): 747
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.
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.
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
7
14
1
3
6
- /*
- 题意为查找区间去重后的和
- 用树状数组离线处理
- 将所有查询以右端点从小到大排序
- 按此顺序边去重边查询
- 前面的去重就不会影响到后面的结果了
- */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int N=;
const int M=; struct node{
int l,r;
int id;
}q[M]; int n,m,val[N],pre[N],loc[];
long long arr[N],res[M]; int lowbit(int x){
return x&(-x);
} void update(int i,int x){
while(i<=n){
arr[i]+=x;
i+=lowbit(i);
}
} long long Sum(int i){
long long ans=;
while(i>){
ans+=arr[i];
i-=lowbit(i);
}
return ans;
} bool cmp(node a,node b){
return a.r<b.r;
} int main(){ //freopen("input.txt","r",stdin); int t;
scanf("%d",&t);
while(t--){
memset(arr,,sizeof(arr));
memset(loc,-,sizeof(loc));
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&val[i]);
pre[i]=loc[val[i]];
loc[val[i]]=i;
update(i,val[i]);
}
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+,q++m,cmp);
int r=;
for(int i=;i<=m;i++){
for(int j=r+;j<=q[i].r;j++)
if(pre[j]!=-)
update(pre[j],-val[j]);
r=q[i].r;
res[q[i].id]=Sum(q[i].r)-Sum(q[i].l-);
}
for(int i=;i<=m;i++)
printf("%I64d\n",res[i]);
}
return ;
}
线段树:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map> using namespace std; const int N=; //#define L(rt) (rt<<1)
//#define R(rt) (rt<<1|1) #define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1 struct Tree{
int l,r;
int id;
}q[N<<]; map<int,int> mp;
int n,m,a[N];
long long sum[N<<],res[N<<]; void PushUp(int rt){
sum[rt]=sum[rt<<]+sum[rt<<|];
} void update(int id,int val,int l,int r,int rt){
if(l==r){
sum[rt]+=val;
return ;
}
int mid=(l+r)>>;
if(id<=mid)
update(id,val,lson);
else
update(id,val,rson);
PushUp(rt);
} long long query(int L,int R,int l,int r,int rt){
if(L<=l && R>=r)
return sum[rt];
int mid=(l+r)>>;
long long ans=;
if(L<=mid)
ans+=query(L,R,lson);
if(R>mid)
ans+=query(L,R,rson);
return ans;
} int cmp(Tree a,Tree b){
return a.r<b.r;
} int main(){ //freopen("input.txt","r",stdin); int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+,q++m,cmp);
mp.clear();
memset(sum,,sizeof(sum));
int r=;
for(int i=;i<=m;i++){
for(int j=r+;j<=q[i].r;j++){
if(mp[a[j]])
update(mp[a[j]],-a[j],,n,);
update(j,a[j],,n,);
mp[a[j]]=j;
r=q[i].r;
}
res[q[i].id]=query(q[i].l,q[i].r,,n,);
}
for(int i=;i<=m;i++)
printf("%I64d\n",res[i]);
}
return ;
}
HDU 3874 Necklace (树状数组 | 线段树 的离线处理)的更多相关文章
- 树状数组 && 线段树应用 -- 求逆序数
参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...
- hdu1394(枚举/树状数组/线段树单点更新&区间求和)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...
- 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树
正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 5147 Sequence II【树状数组/线段树】
Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...
- hdu 1166 敌兵布阵——(区间和)树状数组/线段树
pid=1166">here:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Input 第一行一个整数T.表示有T组数据. 每组数据第一 ...
- HDU 1166 敌兵布阵 树状数组||线段树
http://acm.hdu.edu.cn/showproblem.php?pid=1166 题目大意: 给定n个数的区间N<=50000,还有Q个询问(Q<=40000)求区间和. 每个 ...
- HDU 3303 Harmony Forever 前缀和+树状数组||线段树
Problem Description We believe that every inhabitant of this universe eventually will find a way to ...
- hdu 1166 树状数组(线段树)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
随机推荐
- 关于MySql数据库设计表与查询耗时分析
本地建一张表persons,使用脚本插入了1000万条数据 下面比较几种查询方法的耗时(查询9000000到9000005这中间5条数据) 查询结果: 1: SELECT * FROM test.pe ...
- maven打包时使用的pom配置
<build> <plugins> <!-- compiler插件, 设定JDK版本 --> <plugin> <groupId>org.a ...
- spring:bean的定义
一个完整的Bean的配置文件: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE beans ...
- The vboxdrv kernel module is not loaded
背景: 在没有关虚拟机的情况下, 直接关了电脑, 我的电脑系统是Centos 6 错误的提示: 在终端执行virtualbox -v 时提示 The vboxdrv kernel module is ...
- linux tcp协议状态机
截图来自百度文库 TCP状态-有限状态机
- 使用lock和condition实现的阻塞队列-字符串
在jdk 的API中提供了一个字符串的阻塞队列 : class BoundedBuffer { final Lock lock = new ReentrantLock(); final Conditi ...
- azure之MSSQL服务性能测试
azure给我们提供非常多的服务而这些服务可以让企业轻而易举地在上构建一个健壮的服务体系.但在使用azure的相关产品服务时还是应该对相关的服务有一些简单的性能了解才能更好的让企业购买适合自己的服务产 ...
- node-webkit教程(10)Platform Service之File dialogs
node-webkit教程(10)Platform Service之File dialogs 文/玄魂 目录 node-webkit教程(10)Platform Service之File dialog ...
- 剑指offer 面试题6:重建二叉树
重建二叉树 题目 输入某二叉树的前序遍历和中序遍历,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含有重复的数字. 例如,前序遍历序列:{1,2,3,7,3,5,6,8},中序遍历序列:{ ...
- Lingo 做线性规划 - DEA
Reference: <An Introduction to Management Science Quantitative Approaches to Decision Making, Rev ...