D 区间求和 [数学 树状数组]
2017-05-01 21:49
281 查看
D 区间求和
题意:求\[
\sum_{k=1}^n \sum_{l=1}^{n-k+1} \sum_{r=l+k-1}^n 区间前k大值和
\]
比赛时因为被B卡了没有深入想这道题 结果B没做出来后面的题也没做
化一下式子
\[
\begin{align}
&= \sum_{l=1}^n \sum_{r=l}^n \sum_{k=l}^r a_k \cdot (1+\sum_{i=l}^r [a_i < a_k]) \\
&考虑一个数的贡献 \\
&= \sum_{k=1}^n \sum_{i=k+1}^n a_k \cdot [a_i < a_k] \cdot k \cdot (n-i+1)\\
&+ \sum_{k=1}^n \sum_{i=1}^{k-1} a_k \cdot [a_i < a_k] \cdot i \cdot (n-k+1) \\
&+ \sum_{k=1}^n a_k \cdot k \cdot (n-k+1)
\end{align}
\]
简单的二维偏序问题,树状数组搞一下就行了
注意数相等的情况!第二个二维偏序把相等认为是大于就行了
一定要考虑这种做题方法:
把一些最大值、最小值、k大值之类的关系用求和式子表示出来进行化简
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; const int N = 1e6+5, mo = 1e9+7; inline int read() { char c=getchar(); int x=0,f=1; while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();} return x*f; } int n, a , mp ; ll A, B, C; ll c ; inline void mod(ll &x) {if(x >= mo) x -= mo; else if(x < 0) x += mo;} inline void add(int p, ll v) {for(; p<=n; p+=p&-p) mod(c[p] += v);} inline ll sum(int p) {ll ans=0; for(; p; p-=p&-p) mod(ans += c[p]); return ans;} void solve() { ll ans = 0; for(int k=n; k>=1; k--) mod(ans += (ll) mp[a[k]] * k %mo * sum(a[k]) %mo), add(a[k], (n-k+1)); memset(c, 0, sizeof(c)); for(int k=1; k<=n; k++) mod(ans += (ll) mp[a[k]] * (n-k+1) %mo * sum(a[k]-1) %mo), add(a[k], k); for(int k=1; k<=n; k++) mod(ans += (ll) mp[a[k]] * k %mo * (n-k+1) %mo); printf("%lld\n", (ans + mo) %mo); } int main() { freopen("in", "r", stdin); n=read(); a[1]=read(); A=read(); B=read(); C=read(); for(int i=2; i<=n; i++) a[i] = (a[i-1] * A + B) % C; for(int i=1; i<=n; i++) mp[i] = a[i]; sort(mp+1, mp+1+n); mp[0] = unique(mp+1, mp+1+n) - mp - 1; for(int i=1; i<=n; i++) a[i] = lower_bound(mp+1, mp+1+mp[0], a[i]) - mp; solve(); }
相关文章推荐
- 敌兵布阵------树状数组(单点更新与区间求和)
- 树状数组区间求和三种模型
- 树状数组一、二维区间修改与求和
- HDOJ 1394 Minimum Inversion Number(求逆序数—暴力or线段树or树状数组:单点更新,区间求和)
- HDU 1166 敌兵布阵 树状数组 区间求和
- poj 3468 树状数组解法(解决区间更新,区间求和)
- NYOJ 116 树状数组 基本用法(单点更新,区间求和)
- hdoj 1166 敌兵布阵 【单点更新+区间求和】 【线段树】 【树状数组】
- 树状数组模版(单点修改区间求和)(区间修改单点求值)(区间修改区间求和)
- 20140719 「树状数组 - 区间更新,区间求和」 POJ 3468 A Simple Problem with Integers
- [学习笔记] 树状数组区间加+区间求和
- Hdu 1166 敌兵布阵 树状数组 或 线段树 单点更新,区间求和
- POJ3067 树状数组 情景转化为区间求和
- 敌兵布阵 树状数组 单点更新 区间求和
- 树状数组( 单点修改/区间修改+区间求和+一维/二维)
- poj 3468 树状数组解法(解决区间更新,区间求和)
- 树状数组的区间修改求和
- 【初识——树状数组】 区间求和
- P3374 【模板】树状数组 1(单点增减,区间求和)
- 树状数组区间求和三种模型