2场 J -Subarray

题意:

长度为1e91e9的(1,1)(1,−1)序列,下标从00到1e911e9−1,已知有nn个区间为11,其他为1−1, 问存在多少个区间的和>1>1(保证1inr[i]l[i]+11e7∑1≤i≤nr[i]−l[i]+1≤1e7).

给你一个n 表示有n段连续的1序列 现在问你 在总长度为0~1e9-1的范围内有多少个大于0的子段.

题解

  • 可能作为区间端点的点个数最多为3e73e7
  • f[i]表示以第ii个区间右端点为答案右端点的最大区间和
  • g[i]表示以第ii个区间左端点为答案左端点的最大区间和
  • f[i]=max(0,f[i1](l[i]r[i1]1))+r[i]l[i]+1
  • g[i]=max(0,g[i+1](l[i+1]r[i]1))+r[i]l[i]+1
  • 如果f[i]+g[i+1]l[i+1]r[i]1,说明答案的左右端点可以跨越[r[i]+1,l[i+1]1],那么把这些合并考虑
  • 搞完上面,问题就变成了给你一个长度不超过3e7的(1,−1)序列,问有多少区间和大于1
  • 树状数组时间O(nlogn),稳T
  • 考虑优化:
  • 很好用的性质:每次查询与上次查询的差距等于1
  • 从左到右枚举左端点,统计右边比当前值大的个数
  • 加个标记,标记左移,稳
  •  

#include <iostream>
using namespace std;
 
const int N = 1e6 + 10;
const int M = 4e7 + 10;
 
typedef long long ll;
int l[N], r[N], L[N], R[N];
ll num[M];
 
int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> l[i] >> r[i];
    }
    l[0] = r[0] = L[0] = R[0] = -1, l[n + 1] = r[n + 1] = 1e9;
    int len = 0;
    for (int i = 1; i <= n; i++) {
        len += r[i] - l[i] + 1;
        R[i] = min(r[i] + len, l[i + 1] - 1);
        len -= l[i + 1] - r[i] - 1;
        if (len < 0)
            len = 0;
    }
    len = 0;
    for (int i = n; i >= 1; i--) {
        len += r[i] - l[i] + 1;
        L[i] = max(l[i] - len, r[i - 1] + 1);
        len -= l[i] - r[i - 1] - 1;
        if (len < 0)
            len = 0;
    }
    int now = 2e7 + 10;
    ll sum = 0;
    num[now] = 1;
    ll ans = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = max(L[i], R[i - 1] + 1); j <= R[i]; j++) {
            if (j >= l[i] && j <= r[i]) {
                sum += num[now];
                num[++now]++;
            } else {
                sum -= num[--now];
                num[now]++;
            }
            ans += sum;
        }
    }
    cout << ans << endl;
    return 0;
}
团队通过代码

参考博客:

https://blog.csdn.net/qq_40791842/article/details/96736137

https://blog.csdn.net/qq_40871466/article/details/97104326

https://blog.csdn.net/toohandsomeieaseid/article/details/98848517

https://www.cnblogs.com/Yinku/p/11221494.html

https://www.cnblogs.com/wmj6/p/11288038.html

posted @ 2019-08-14 20:04  Young-children  阅读(137)  评论(0编辑  收藏  举报