题意:

给出一个长度为\(n\)的数列\(A_i\),定义\(f(k)\)为所有长度大于等于\(k\)的子区间中前\(k\)大数之和的和。

求\(\sum_{k=1}^{n}f(k) \; mod \; 10^9+7\)。

分析:

从某个长度为\(k\)的子区间对答案的贡献来看:

它的长度大于等于\(k\),所以区间中每个都加到答案中一次。

它的长度还大于等于\(k-1\),区间中前\(k-1\)大的数加到答案中一次。

……

以此类推。

对于每个数\(A_i\):如果这个区间中有\(x\)个小于\(A_i\)的数,这个数对答案就会贡献\(x+1\)次。

所以如果存在\(A_i<A_j,i<j\),包含这两个数区间的个数为\(i \times (n - j + 1)\),

对答案的贡献为\(A_j \cdot i \cdot (n - j + 1)\)。

\(A_i<A_j,i>j\)的情况类似,所以可以枚举\(A_j\),求和用一个树状数组维护。

  • 对于数字相等的情况还是要区分开来的,可以用它们的下标再比较一次大小,这样做到了不重不漏。
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <map>
  5. #include <set>
  6. #include <vector>
  7. #include <iostream>
  8. #include <string>
  9. using namespace std;
  10. #define REP(i, a, b) for(int i = a; i < b; i++)
  11. #define PER(i, a, b) for(int i = b - 1; i >= a; i--)
  12. #define SZ(a) ((int)a.size())
  13. #define MP make_pair
  14. #define PB push_back
  15. #define EB emplace_back
  16. #define ALL(a) a.begin(), a.end()
  17. #define F first
  18. #define S second
  19. #define lowbit(x) (x&(-x))
  20. typedef long long LL;
  21. typedef pair<LL, int> PII;
  22. const int maxn = 1000000 + 10;
  23. const LL MOD = 1000000007LL;
  24. LL mul(LL a, LL b) { return a * b % MOD; }
  25. void add(LL& a, LL b) { a += b; if(a >= MOD) a -= MOD; }
  26. int n;
  27. LL A, B, C;
  28. LL a[maxn];
  29. PII b[maxn];
  30. LL bit[maxn];
  31. void init() { memset(bit, 0, sizeof(bit)); }
  32. void update(int x, int v) {
  33. while(x <= n) {
  34. add(bit[x], v);
  35. x += lowbit(x);
  36. }
  37. }
  38. int query(int x) {
  39. LL ans = 0;
  40. while(x) {
  41. add(ans, bit[x]);
  42. x -= lowbit(x);
  43. }
  44. return ans;
  45. }
  46. int main() {
  47. scanf("%d%lld%lld%lld%lld", &n, &a[1], &A, &B, &C);
  48. A %= C; B %= C;
  49. b[1].F = a[1];
  50. b[1].S = 1;
  51. REP(i, 2, n + 1) {
  52. a[i] = ((a[i - 1] * A) % C) + B;
  53. if(a[i] >= C) a[i] -= C;
  54. b[i].F = a[i];
  55. b[i].S = i;
  56. }
  57. sort(b + 1, b + 1 + n);
  58. REP(i, 1, n + 1)
  59. a[i] = lower_bound(b + 1, b + 1 + n, MP(a[i], i)) - b;
  60. LL ans = 0;
  61. REP(i, 1, n + 1) {
  62. update(a[i], i);
  63. LL t = mul(b[a[i]].F, (LL)(n - i + 1));
  64. add(ans, mul(query(a[i]), t));
  65. }
  66. init();
  67. PER(i, 1, n + 1) {
  68. LL t = mul(b[a[i]].F, (LL)i);
  69. add(ans, mul(query(a[i]), t));
  70. update(a[i], n - i + 1);
  71. }
  72. printf("%lld\n", ans);
  73. return 0;
  74. }

51Nod 1680 区间求和 树状数组的更多相关文章

  1. nyoj--108--士兵杀敌(一)(区间求和&&树状数组)

    士兵杀敌(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军现在想知 ...

  2. 51nod_1199 树的先跟遍历+区间更新树状数组

    题目是中文,所以不讲题意 做法顺序如下: 使用先跟遍历,把整棵树平铺到一维平面中 使用自己整的区间更新树状数组模板进行相关操作. http://www.cnblogs.com/rikka/p/7359 ...

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

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

  4. 区间操作---树状数组&&线段树

    涉及区间操作的一些套路必须要会呀 区间加减为了偷懒能不写线段树so我选择树状数组!! 但是区间乘除,最大值我想了想还是用线段树分块吧. 树状数组: 这里用网上的一张图: 这里灰色数组是原本的数组(a[ ...

  5. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询

    点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...

  6. ACM学习历程—HDU5700 区间交(树状数组 && 前缀和 && 排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=5700 这是这次百度之星初赛2B的第五题.省赛回来看了一下,有这样一个思路:对于所有的区间排序,按左值排序. 然后 ...

  7. 51Nod 1272最大距离 (树状数组维护前缀最小值)

    题目链接 最大距离 其实主流解法应该是单调栈……我用了树状数组. #include <bits/stdc++.h> using namespace std; #define rep(i, ...

  8. 51nod 1681 公共祖先 | 树状数组

    51nod 1681 公共祖先 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完 ...

  9. 51nod 1081 子段求和(线段树 | 树状数组 | 前缀和)

    题目链接:子段求和 题意:n个数字序列,m次询问,每次询问从第p个开始L长度序列的子段和为多少. 题解:线段树区间求和 | 树状数组区间求和 线段树: #include <cstdio> ...

随机推荐

  1. 被遗忘的设计模式——空对象模式(Null Object Pattern)

    GoF(四人帮)那本<设计模式 可复用面向对象软件的基础>可谓是设计模式方面的经典之作,其中介绍的23种设计模式, 也可谓是经典中的经典.但是,设计模式的种类绝不仅仅是这23种,除此之外还 ...

  2. git/github初级运用自如(转自:虫师)

    注:本文来源于 虫师博客(http://www.cnblogs.com/fnng/archive/2012/01/07/2315685.html) ,内容详尽,真实有用. 另:发一个github使用教 ...

  3. Selenium入门18 断言

    自动化测试需对比实际结果与预期结果,给出测试结论. 1 条件判断 if ...else... 2 assert ... #coding:utf-8 #断言 from selenium import w ...

  4. 打表格,字符串处理,POJ(2136)

    题目链接:http://poj.org/problem?id=2136 水题WA了半天,结果是数组开小了. #include <stdio.h> #include <string.h ...

  5. 模拟猜数(POJ2328)

    题目链接:http://poj.org/problem?id=2328 解题报告: 缩短区间,soeasy, #include <stdio.h> #include <stdlib. ...

  6. next_permutation暴力搜索,POJ(3187)

    题目链接:http://poj.org/problem?id=3187 解题报告: #include <stdio.h> #include <iostream> #includ ...

  7. leetcode_No.1 Two Sum

    原题: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  8. npy数据的保存与读取

    保存 利用这种方法,保存文件的后缀名字一定会被置为.npy x = numpy.save("data_x.npy",x) 读取 data = numpy.load("da ...

  9. Intel MKL 多线程设置

    对于多核程序,多线程对于程序的性能至关重要. 下面,我们将对Intel MKL 有关多线程方面的设置做一些介绍: 我们提到MKL 支持多线程,它包括的两个概念:1>MKL 是线程安全的: MKL ...

  10. Visual Studio Code快捷键_Linux

    Keyboard shortcuts for Linux Basic editing Ctrl + X Cut line(empty selection) Ctrk + C   Copy line(e ...