http://codeforces.com/contest/813/problem/E

题目大意:

给出长度为n的数组和k,  大小是1e5级别。

要求在线询问区间[l, r]权值,  权值定义为对于所有不同元素x在区间出现的次数和, 如果x出现次数>k, 那么按k算。

重要转换: 考虑一个区间[L, R]的某个数A[i], 它对答案有贡献 当且仅当 它前面与他权值相同的数中第k个数的位置(记为B[i]) < L

预处理B[], 每次询问就转化为 区间[L, R]中有多少个B[i] < L

可以用主席树 或者 分块解决。

也可以用此题的方法求区间不同元素个数, 其实就是k = 1的情况。

主席树代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <map>
  8. #include <queue>
  9. using namespace std;
  10.  
  11. typedef long long ll;
  12.  
  13. #define N 100050
  14. const int INF = << ;
  15. const double pi = acos(-);
  16.  
  17. int pt;
  18. int a[N], b[N], root[N], lc[N * ], rc[N * ], cnt[N * ];
  19. vector<int> lis[N];
  20.  
  21. int Add(int y, int l, int r, int v)
  22. {
  23. int x = ++pt;
  24. cnt[x] = cnt[y] + ;
  25. if (l < r)
  26. {
  27. int mid = (l + r) >> ;
  28. if (v <= mid)
  29. {
  30. rc[x] = rc[y];
  31. lc[x] = Add(lc[y], l, mid, v);
  32. }
  33. else
  34. {
  35. lc[x] = lc[y];
  36. rc[x] = Add(rc[y], mid + , r, v);
  37. }
  38. }
  39. return x;
  40. }
  41.  
  42. int Query(int x, int y, int L, int R, int l, int r)
  43. {
  44. //cout << L <<" " << R << " " << cnt[x] << " " << cnt[y] << endl;
  45. if (l > R || r < L) return ;
  46. if (l <= L && r >= R) return cnt[x] - cnt[y];
  47.  
  48. int Mid = (L + R) >> ;
  49. return Query(lc[x], lc[y], L, Mid, l, r) + Query(rc[x], rc[y], Mid + , R, l, r);
  50. }
  51.  
  52. int main()
  53. {
  54. //freopen("in.in", "r", stdin);
  55. //freopen("out.out", "w", stdout);
  56.  
  57. int n, k, Q, lastans = , l, r;
  58. scanf("%d %d", &n, &k);
  59. for (int i = ; i <= n; ++i) scanf("%d", &a[i]), lis[a[i]].push_back(i);
  60.  
  61. for (int i = ; i <= ; ++i)
  62. {
  63. if (lis[i].size() <= k) continue;
  64. for (int j = k; j < lis[i].size(); ++j) b[lis[i][j]] = lis[i][j - k];
  65. }
  66.  
  67. root[] = ++pt;
  68. for (int i = ; i <= n; ++i) root[i] = Add(root[i - ], , n, b[i]);
  69.  
  70. scanf("%d", &Q);
  71. while (Q--)
  72. {
  73. scanf("%d %d", &l, &r);
  74. l = (l + lastans) % n + ;
  75. r = (r + lastans) % n + ;
  76. if (l > r) swap(l, r);
  77. lastans = Query(root[r], root[l - ], , n, , l - );
  78. printf("%d\n", lastans);
  79. }
  80.  
  81. return ;
  82. }

分块代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <map>
  8. #include <queue>
  9. using namespace std;
  10.  
  11. typedef long long ll;
  12.  
  13. #define N 100050
  14. const int INF = << ;
  15. const double pi = acos(-);
  16.  
  17. int pt;
  18. int a[N], b[N], id[N], dp[][N];
  19. int bl[], br[];
  20. vector<int> lis[N];
  21.  
  22. int main()
  23. {
  24. //freopen("in.in", "r", stdin);
  25. //freopen("out.out", "w", stdout);
  26.  
  27. int n, k, Q, lastans = , l, r;
  28. scanf("%d %d", &n, &k);
  29. for (int i = ; i <= n; ++i) scanf("%d", &a[i]), lis[a[i]].push_back(i);
  30.  
  31. for (int i = ; i <= ; ++i)
  32. {
  33. if (lis[i].size() <= k) continue;
  34. for (int j = k; j < lis[i].size(); ++j) b[lis[i][j]] = lis[i][j - k];
  35. }
  36.  
  37. int block = (int)sqrt(n + );
  38.  
  39. for (int i = ; ; ++i)
  40. {
  41. l = (i - ) * block + ;
  42. r = min(n, l + block - );
  43. bl[i] = l, br[i] = r;
  44. for (int j = l; j <= r; ++j) dp[i][b[j]]++, id[j] = i;
  45. for (int j = ; j <= ; ++j) dp[i][j] += dp[i][j - ];
  46. if (r == n) break;
  47. }
  48.  
  49. scanf("%d", &Q);
  50. while (Q--)
  51. {
  52. scanf("%d %d", &l, &r);
  53. l = (l + lastans) % n + ;
  54. r = (r + lastans) % n + ;
  55. if (l > r) swap(l, r);
  56.  
  57. int res = ;
  58. if (id[l] == id[r])
  59. {
  60. for (int i = l; i <= r; ++i)
  61. res += b[i] < l;
  62. }
  63. else
  64. {
  65. for (int i = l; i <= br[id[l]]; ++i) res += b[i] < l;
  66. for (int i = bl[id[r]]; i <= r; ++i) res += b[i] < l;
  67. for (int i = id[l] + ; i <= id[r] - ; ++i) res += dp[i][l - ];
  68. }
  69. printf("%d\n", res);
  70. lastans = res;
  71. }
  72.  
  73. return ;
  74. }

Educational Codeforces Round 22 E. Army Creation 主席树 或 分块的更多相关文章

  1. Educational Codeforces Round 22 E. Army Creation

    Educational Codeforces Round 22 E. Army Creation 题意:求区间[L,R]内数字次数不超过k次的这些数字的数量的和 思路:和求区间内不同数字的数量类似,由 ...

  2. Educational Codeforces Round 22 E. Army Creation(分块好题)

    E. Army Creation time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  3. [Educational Codeforces Round#22]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 晚上去clj博客逛来逛去很开心,突然同学提醒了一下,发现cf已经开始40分钟了,慌的一B,从B题开始写,写完了B到E最后收掉了A,结果太着急B ...

  4. Educational Codeforces Round 22 补题 CF 813 A-F

    A The Contest 直接粗暴贪心 略过 #include<bits/stdc++.h> using namespace std; int main() {//freopen(&qu ...

  5. Educational Codeforces Round 22.B 暴力

    B. The Golden Age time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  6. Educational Codeforces Round 22 B. The Golden Age(暴力)

    题目链接:http://codeforces.com/contest/813/problem/B 题意:就是有一个数叫做不幸运数,满足题目的 n = x^a + y^b,现在给你一个区间[l,r],让 ...

  7. 【Educational Codeforces Round 22】

    又打了一场EDU,感觉这场比23难多了啊…… 艹还是我太弱了. A. 随便贪心一下. #include<bits/stdc++.h> using namespace std; ,ans=- ...

  8. CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组

    题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点 ...

  9. Educational Codeforces Round 12 E. Beautiful Subarrays 字典树

    E. Beautiful Subarrays 题目连接: http://www.codeforces.com/contest/665/problem/E Description One day, ZS ...

随机推荐

  1. nginx安装说明

    下载地址:http://nginx.org/en/download.html 安装版本:1.10.0 安装配置如下: /etc/nginx 目录 /home/nginx目录 --prefix=/hom ...

  2. Python strings, 元组tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的

    在python中,strings, 元组tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象. a = 1 def fun(a):     a = 2 fun(a ...

  3. Django 学习记录

    这是我自己理解并自己画的,django 请求示意图,表示了它的组织方式. project manage.py: 主要工具文件 settings.py: 配置文件 urls.py: url 定义及其指向 ...

  4. selenium-Navigating

    The first thing you’ll want to do with WebDriver is navigate to a link. The normal way to do this is ...

  5. Unity3D系列教程--使用免费工具在Unity3D中开发2D游戏 第一节

    声明:   本博客文章翻译类别的均为个人翻译,版权全部.出处: http://blog.csdn.net/ml3947,个人博客:http://www.wjfxgame.com. 译者说明:这是一个系 ...

  6. 【构建Android缓存模块】(一)吐槽与原理分析

    http://my.oschina.net/ryanhoo/blog/93285 摘要:在我翻译的Google官方系列教程中,Bitmap系列由浅入深地介绍了如何正确的解码Bitmap,异步线程操作以 ...

  7. 【DB2】DbVisualizer编译存储过程

    之前我一直以为DbVisualizer是不可以编译存储过程的,现在才发现是可以的,编译如下: 只需要在编译的时候注意使用--/与/将存储过程包为起来编辑即可.

  8. JavaMelody、prob系统监控工具使用配置

    分类: 工具 2014-04-23 14:41 1857人阅读 评论(1) 收藏 举报 目录(?)[+] 项 目开发结束了,需要做一下压力测试,就使用apache自带的ab程序进行压力测试,300个并 ...

  9. 基于vue单页应用的例子

    代码地址如下:http://www.demodashi.com/demo/13374.html 目录结构 src目录 主要的代码目录 components 存放项目组件 router 路由文件 sto ...

  10. Workshop:用Python做科学计算

    Python是程序史上最流行的开源语言之一. 仅在官方包索引PyPi上就已经发布了超过10万个开源软件包,而且还有更多的项目. 在SciPy的麾下,有一个成熟的python包生态系统,可以使用Pyth ...