题意 : 给出一段n个数的序列,接下来给出m个询问,询问的内容SPOJ是(L, R)这个区间内不同的数的个数,HDU是不同数的和

分析 :

一个经典的问题,思路是将所有问询区间存起来,然后按右端点排序

最后从左到右将原区间扫一遍,扫的过程当中不断将重复出现的数字右移

也就是如果一个数字重复出现,那么我们记录最右边的那个为有效的,其他都视为不存在

这样一旦遇到一个问询区间的右端点就线段树查询即可。

SPOJ:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define lson l , m , rt << 1
  4. #define rson m + 1 , r , rt << 1 | 1
  5. ;
  6. ];
  7. void PushUP(int rt) {
  8. sumv[rt] = sumv[rt<<] + sumv[rt<<|];
  9. }
  10. void update(int p,int sc,int l,int r,int rt) {
  11. if (l == r) {
  12. sumv[rt] += sc;
  13. return ;
  14. }
  15. );
  16. if (p <= m) update(p , sc , lson);
  17. else update(p , sc , rson);
  18. PushUP(rt);
  19. }
  20.  
  21. long long query(int L,int R,int l,int r,int rt) {
  22. if (L <= l && r <= R) {
  23. return sumv[rt];
  24. }
  25. );
  26. ;
  27. if (L <= m) ret += query(L , R , lson);
  28. if (R > m) ret += query(L , R , rson);
  29. return ret;
  30. }
  31. struct Interval{
  32. int l, r, id;
  33. bool operator < (const Interval& other) const{
  34. return this->r < other.r;
  35. }
  36. };
  37. Interval sec[];
  38. map<int, int> mp;
  39. int arr[maxn];
  40. int pre[maxn];
  41. long long ans[maxn];
  42. int main(void)
  43. {
  44. , m;
  45. scanf("%d", &n);
  46. ; i<=n; i++){
  47. scanf("%d", &arr[i]);
  48. if(!mp.count(arr[i]))
  49. mp[arr[i]] = cnt++;//区间上的每一个数都有一个独特的编号,使用map来进行映射,目的是方便判断此数是否已经重复出现过
  50. }
  51. scanf("%d", &m);
  52. ; i<=m; i++){
  53. scanf("%d %d", &sec[i].l, &sec[i].r);
  54. sec[i].id = i;//因为后续有排序操作,而我们又要对问询答案顺序给出,所以记录给出的顺序,方便输出答案
  55. }
  56. sort(sec+, sec++m);//按照右端点排序
  57. bool vis[maxn];
  58. memset(vis, false, sizeof(vis));
  59. , j=; j<=m && i<=n; i++){
  60. int tmp = mp[arr[i]];//拿出这个数的编号
  61. if(vis[tmp]){//如果这个数在前面已经访问过
  62. update(pre[tmp], -, , n, );//将之前的位置信息抹去
  63. update(i, , , n, );//当前的位置才是有效的,所以给当前位置+1
  64. pre[tmp] = i;//更新pre数组方便下次操作
  65. }else{
  66. vis[tmp] = true;
  67. update(i, , , n, );
  68. pre[tmp] = i;
  69. }
  70. while(sec[j].r == i){
  71. ans[sec[j].id] = query(sec[j].l, sec[j].r, , n, );
  72. j++;
  73. }
  74. }
  75. ; i<=m; i++){
  76. printf("%I64d\n", ans[i]);
  77. }
  78.  
  79. ;
  80. }

HDU:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define lson l , m , rt << 1
  4. #define rson m + 1 , r , rt << 1 | 1
  5. ;
  6. ];
  7. void PushUP(int rt) {
  8. sumv[rt] = sumv[rt<<] + sumv[rt<<|];
  9. }
  10. void update(int p,long long sc,int l,int r,int rt) {
  11. if (l == r) {
  12. sumv[rt] += sc;
  13. return ;
  14. }
  15. );
  16. if (p <= m) update(p , sc , lson);
  17. else update(p , sc , rson);
  18. PushUP(rt);
  19. }
  20. long long query(int L,int R,int l,int r,int rt) {
  21. if (L <= l && r <= R) {
  22. return sumv[rt];
  23. }
  24. );
  25. ;
  26. if (L <= m) ret += query(L , R , lson);
  27. if (R > m) ret += query(L , R , rson);
  28. return ret;
  29. }
  30. struct interval{
  31. int L, R, id;
  32. bool operator < (const interval & other) const{
  33. return this->R < other.R;
  34. }
  35. };
  36. interval sec[maxn<<];
  37. bool vis[maxn];
  38. ];
  39. int per[maxn];
  40. long long arr[maxn];
  41. map<long long, int> mp;
  42. int main(void)
  43. {
  44. int nCase;
  45. scanf("%d", &nCase);
  46. while(nCase--){
  47. int n;
  48. mp.clear(); ;
  49. memset(sumv, , sizeof(sumv));
  50. scanf("%d", &n);
  51. ; i<=n; i++){
  52. scanf("%I64d", &arr[i]);
  53. if(!mp.count(arr[i]))
  54. mp[arr[i]] = cnt++;
  55. }
  56. int m;
  57. scanf("%d", &m);
  58. ; i<=m; i++){
  59. scanf("%d %d", &sec[i].L, &sec[i].R);
  60. sec[i].id = i;
  61. }
  62. sort(sec+, sec++m);
  63. memset(vis, false, sizeof(vis));
  64. , j=; j<=m && i<=n; i++){
  65. int num = mp[arr[i]];
  66. if(vis[num]){
  67. update(per[num],-arr[i],,n,);
  68. update(i, arr[i], , n, );
  69. per[num] = i;
  70. }else{
  71. vis[num] = true;
  72. update(i, arr[i], , n, );
  73. per[num] = i;
  74. }
  75. while(i==sec[j].R){
  76. ans[sec[j].id] = query(sec[j].L, sec[j].R, , n, );
  77. j++;
  78. }
  79. }
  80. ; i<=m; i++){
  81. printf("%I64d\n", ans[i]);
  82. }
  83. }
  84. }

update in 2018-06-08

学了主席树、以上的离线算法都可以变成在线算法了、戳 主席树

SPOJ D-query && HDU 3333 Turing Tree (线段树 && 区间不相同数个数or和 && 离线处理)的更多相关文章

  1. HDU 3333 Turing Tree 线段树+离线处理

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Othe ...

  2. HDU 3333 Turing Tree (线段树)

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  3. HDU 3333 Turing Tree(树状数组/主席树)

    题意 给定一个长度为 \(n​\) 的序列,\(m​\) 个查询,每次查询区间 \([L,R]​\) 范围内不同元素的和. \(1\leq T \leq 10\) \(1 \leq n\leq 300 ...

  4. HDU 3333 Turing Tree (主席树)

    题意:给定上一个序列,然后有一些询问,求区间 l - r 中有多少个不同的数的和. 析:和求区间不同数的方法是一样,只要用主席树维护就好. 代码如下: #pragma comment(linker, ...

  5. SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

  6. W同学的新画板 QDUOJ 线段树 区间颜色段数

    W同学的新画板 QDUOJ 线段树 区间颜色段数 原题链接 题意 W同学在每天的刻苦学习完成功课之余,都会去找一些有趣的事情来放松自己:恰巧今天他收到了朋友送给他的一套画板,于是他立刻拆开了包装,拿出 ...

  7. hdu 3333 Turing Tree 图灵树(线段树 + 二分离散)

    http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Others)    ...

  8. hdu 3333 Turing Tree(线段树+离散化)

    刚看到是3xian大牛的题就让我菊花一紧,觉着这题肯定各种高端大气上档次,结果果然没让我失望. 刚开始我以为是一个普通的线段树区间求和,然后啪啪啪代码敲完测试没通过,才注意到这个求和是要去掉相同的值的 ...

  9. HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举

    HDU 6638 - Snowy Smile 题意 给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大. 思路 先离散化纵坐标\(y ...

随机推荐

  1. flask response 详解

    from flask import Flask,Response,jsonify #Flask = werkzeug(处理网络的) + sqlalchemy(处理数据库的) + jinja2 (处理模 ...

  2. angular - ngFor, trackby

    ngFor ngForOf指令通常使用缩写形式*ngFor为集合中的每个项呈现模板的结构指令.该指令放置在元素上,该元素将成为克隆模板的父级. <li *ngFor="let item ...

  3. 小记-----如何把本地jar包加载到maven库中

    1.从maven中央库下载下jar包

  4. Spring(四)--bean的属性赋值

    bean的属性赋值 1.需要的实体类 2.需要的配置文件 <?xml version="1.0" encoding="UTF-8"?> <be ...

  5. Spring(二)--Spring入门案例

    Spring入门案例 1.需要的实体类 2.需要的接口和实现类 3.需要的service和实现类 /** * service层的作用 * 在不改变dao层代码的前提下,增加业务逻辑操作 */ publ ...

  6. MyBatis一级缓存的笔记及记录

    精髓内容来源于<图灵学院> 一.概述: 一级缓存是MyBatis天然自带的,是默认开启且没有关闭的地方,1级缓存只能作用于查询回话中,所以也叫会话缓存: 这里举个例子: 订单表存在一对多的 ...

  7. 2019CCPC厦门游记

    距离上次2018CCPC吉林打铁一年有余,这次的厦门也是我们team拿到的第一块区域赛牌子,写一篇博客留念一下QAQ. 作为弱校的菜鸡队,我们提前两天就来到厦门,不得不说刚到厦门的两天还是很快乐的,住 ...

  8. [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)

    [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...

  9. jquery html select 清空保留第一项

    <select id="a"> <option>1</option> <option>2</option> <op ...

  10. css精灵图使用

    1. 精灵技术的使用 CSS 精灵其实是将网页中的一些背景图像整合到一张大图中(精灵图),然而,各个网页元素通常只需要精灵图中不同位置的某个小图,要想精确定位到精灵图中的某个小图,就需要使用CSS的b ...