链接:https://ac.nowcoder.com/acm/contest/1084/B
来源:牛客网

Galahad
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
本题推荐BGM:Galahad and Scientific Witchery

魔女要测试骑士的能力,要求他维护一个长度为 的序列,每次要询问一个区间的和。

但是魔女觉得太简单了,骑士能轻松记住 个数作为前缀和。

于是,魔女要求他回答一个区间的和,但如果某一个数在这个区间出现了多次,这个数只能被计算一次。

输出描述:
输出 行,每行一个整数表示这次询问的答案。
示例1
输入
复制

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

输出
复制

6
4
5

/*
区间不同数字个数板子一样~
*/
解法一:
数状数组:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MAXN = 5e5+5;
int a[MAXN];
LL b[MAXN];
LL ans[MAXN];
int n,m;
struct Node
{int l,r;int id;bool operator<(const Node &a)const{return r < a.r;}
} node[MAXN];
int last[MAXN];
inline int lowbit(int x)
{return x&-x;
}
void add(int x,int v)
{for(int i = x; i <= n; i+=lowbit(i)){b[i] += v;}
}
LL sum(int x)
{LL res = 0;for(int i = x; i > 0; i-=lowbit(i)){res += b[i];}return res;
}
int main()
{scanf("%d%d",&n,&m);for(int i = 1; i <= n; i++){scanf("%d",&a[i]);}for(int i = 1; i <= m; i++){scanf("%d%d",&node[i].l,&node[i].r);node[i].id = i;}/*按询问区间中r小的优先排序(r递增排序)这样维护的时候就可以只保留最后一个不重复的数字*/sort(node+1,node+m+1);for(int i = 1; i <= m; i++){for(int j = node[i-1].r+1; j <= node[i].r; j++){if(last[a[j]])//前面出现过,那个位置置为0add(last[a[j]],-a[j]);add(j,a[j]);//当前位置加当前位置对应的值last[a[j]] = j;//记录位置}ans[node[i].id] = sum(node[i].r)-sum(node[i].l-1);}for(int i = 1; i <= m; i++){printf("%lld\n",ans[i]);}return 0;
}

解法二:
线段树:

#include <bits/stdc++.h>
#define lson rt<<1,l, mid
#define rson rt<<1|1,mid+1,r
using namespace std;
const int N = 5e5+5;
typedef long long LL;
LL sum[N<<2];
int a[N];
int last[N];
LL ans[N];
struct Node
{int l,r;int id;bool operator<(const Node &a)const{return r < a.r;}
} node[N];
inline void push_up(int rt)
{sum[rt] = sum[rt<<1]+sum[rt<<1|1];
}
/*
void build(int rt,int l,int r)
{if(l == r) //叶子节点{sum[l] = a[l];return;}int mid = (l+r)>>1;//建左子树build(lson);//建右子树build(rson);//向上更新信息push_up(rt);
}
*/
//单点更新
void update_point(int pos,int v,int rt,int l,int r)
{if(l == r){sum[rt] = v;return;}int mid = (l+r) >> 1;if(pos <= mid) //在左子树update_point(pos,v,lson);elseupdate_point(pos,v,rson);//向上更新信息push_up(rt);
}
//区间查询,查询【L,R】
LL query(int L,int R,int rt,int l,int r)
{if(L <= l && r <= R) //是查询区间子集{return sum[rt];}int mid = (l + r) >> 1;LL res = 0;if(L <= mid) res += query(L,R,lson);if(R > mid) res += query(L,R,rson);return res;}
int main()
{int n,m;scanf("%d%d",&n,&m);for(int i = 1; i <= n; i++){scanf("%d",&a[i]);}for(int i = 1; i <= m; i++){scanf("%d%d",&node[i].l,&node[i].r);node[i].id = i;}sort(node+1,node+m+1);//build(1,1,n);for(int i = 1; i <= m; i++){for(int j = node[i-1].r+1; j <= node[i].r; j++){if(last[a[j]])update_point(last[a[j]],0,1,1,n);last[a[j]] = j;update_point(j,a[j],1,1,n);}ans[node[i].id] = query(node[i].l,node[i].r,1,1,n);}for(int i = 1; i <= m; i++){printf("%lld\n",ans[i]);}return 0;
}

Galahad(板子:区间不重复数字的和,树状数组/线段树)相关推荐

  1. D-query SPOJ - DQUERY(求区间不同数的个数)(树状数组||线段树+离散)(主席树+在线)

    English Vietnamese Given a sequence of n numbers a1, a2, -, an and a number of d-queries. A d-query ...

  2. 51nod 1680区间求和 (dp+树状数组/线段树)

    不妨考虑已知一个区间[l,r]的k=1.k=2....k=r-l+1这些数的答案ans(只是这一个区间,不包含子区间) 那么如果加入一个新的数字a[i](i = r+1) 则新区间[l, i]的答案为 ...

  3. E. Tyler and Strings(组合计数 + 树状数组/线段树)(带重复元素的全排列)

    题目链接 主要思路还是比较好想的,一些细节公式预处理比较难搞- 参考题解 分析 从前往后遍历,如果s[]剩下的数中,s[i] < t[i]则对答案是有贡献的: 贡献就是后面位置[i+1 ~ n] ...

  4. AcWing - 246. 区间最大公约数(树状数组+线段树)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,需要执行 mmm 次操作,每次操作分为下列两种类型: C l r d:将区间 [l,r][l,r][l,r] 位置的数字都加上 ddd Q ...

  5. 【LuoguP3038/[USACO11DEC]牧草种植Grass Planting】树链剖分+树状数组【树状数组的区间修改与区间查询】...

    模拟题,可以用树链剖分+线段树维护. 但是学了一个厉害的..树状数组的区间修改与区间查询.. 分割线里面的是转载的: ----------------------------------------- ...

  6. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  7. 数据结构一【树状数组】普通、二维、离线树状数组的(单点修改,单点查询,区间修改,区间查询)模板及应用例题总结

    文章目录 树状数组 lowbit 线段树与树状数组 单点修改 区间查询 区间修改 区间求和 二维树状数组 离线树状数组 例题 POJ:stars MooFest [SDOI2009]HH的项链 Tur ...

  8. 牛客练习赛52.Galahad(树状数组维护区间不相同数的和)

    链接:https://ac.nowcoder.com/acm/contest/1084/B 来源:牛客网 Galahad 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K ...

  9. 牛客练习赛52 B:Galahad(树状数组维护区间不同元素和(个数))

    [题目] 查询区间和,如果区间元素重复出现则计数一次. [题解] 按区间的右端点建立树状数组,维护区间[1,R]的每个元素的最右位置.按查询区间的右端点排序,依次处理,每次更新当前值的最右位置即可. ...

最新文章

  1. ecs和eks 比较_如何使用Kubernetes,EKS和NGINX为网站设置DNS
  2. Key Components and Internals of Spring Boot Framework--转
  3. java集合使用_java集合使用初步
  4. 分布式系统原理 之5 日志技术
  5. Java 字符串操作的总结1(转载)
  6. python filestorage对象怎么转化成字符串_Python面试的10个常见问题及答案,检验你的学习成果吧!...
  7. pandas dataframe对多列同时排序
  8. 数字化落后,工业就挨打!
  9. 一堂如何提高代码质量的培训课 之 领域驱动设计
  10. 【比原链】比原启动后去哪里连接别的节点
  11. R语言:关于我国各地区消费水平的聚类分析
  12. 任务接单平台源码自动挂机阅读文章挣钱系统
  13. 解决CentOS7下用ntpdate同步时间问题
  14. GitHub Error: API rate limit exceeded
  15. android发送http post请求函数带参数带返回数据 静态类 源码
  16. 2021年美赛B题目简述(中英文)
  17. 数论概论读书笔记 13.素数的计数
  18. 十天搞定考研词汇 ---转发
  19. 成功解决龙猫饲养的一大难题:乱撒尿
  20. [词根词缀]greg/hap/helio及词源G与H的故事

热门文章

  1. AWK用法示例 awk命令
  2. 使用awk提取文本 awk处理条件 awk流程控制 awk扩展应用
  3. (理财六)贷款用途的分类
  4. Base 64 编码
  5. Android开发-简介(一)
  6. 讯飞离线语音命令词识别
  7. Table边框使用总结 ,只显示你要显示的边框
  8. 牛客网计算机考研机试真题-abc
  9. git 误删分支恢复方法
  10. [美国签证]准备材料及面签过程