zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第二场)J.Subarray

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

    思路:假设我们统计了当前的前缀和 我们显然可以用树状数组维护一下前缀和 这样我们可以nlogn算出答案 但是对于1e7的数据 这样处理肯定会超时 所以我们考虑前缀和是一个每次变化都是1的折线

    我们可以直接数组模拟lazy来求出答案

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e7+7;
    const int inf = 0x3f3f3f3f;
    typedef long long ll;
    const ll mod = 1e7+9;
    int l[N],r[N];
    int f[N],g[N],sum[3*N];
    int b[3*N],c[3*N];
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        int n; cin>>n;
        for(int i=1;i<=n;i++){
            cin>>l[i]>>r[i];
        }
        f[1]=r[1]-l[1]+1;
        for(int i=2;i<=n;i++)
            f[i]=max(r[i]-l[i]+1,f[i-1]-(l[i]-r[i-1]-1)+r[i]-l[i]+1);
        g[n]=r[n]-l[n]+1;
        for(int i=n-1;i>=1;i--)
            g[i]=max(r[i]-l[i]+1,g[i+1]-(l[i+1]-r[i]-1)+r[i]-l[i]+1);
        int i=1; int now=1e7;
        ll ans=0;
        while(i<=n){
            int j=i+1;
            while(j<=n&&g[j]+f[j-1]>=(l[j]-r[j-1]-1)){
                j++;
            }
            j--;
            int le=max(0,l[i]-g[i]); int ri=min(int(1e9)-1,r[j]+f[j]);
            int t=i; int mx,mi; mx=-1; mi=inf;
            for(int k=le;k<=ri;k++){
                if(k>=l[t]&&k<=r[t])
                    sum[k-le+1]=sum[k-le]+1;
                else
                    sum[k-le+1]=sum[k-le]-1;
                if(k==r[t]) t++;    
                mx=max(mx,sum[k-le+1]+now);
                mi=min(mi,sum[k-le+1]+now);
                b[sum[k-le+1]+now]++;
            }
            for(int k=mx-1;k>=mi;k--)
                b[k]+=b[k+1];
            ans+=b[now+1];
            for(int k=le;k<=ri;k++){
                t=sum[k-le+1]+now;
                b[t+1]-=c[t+1];
                c[t]+=c[t+1]+1;
                c[t+1]=0;
                ans+=b[t+1];
            }
            for(int k=mi;k<=mx;k++)
                b[k]=0,c[k]=0;
            i=j+1;
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    bzoj 维护序列seq(双标记线段树)
    kmp算法总结
    2013蓝桥杯
    Longge的问题(欧拉,思维)
    mode(思维,注意内存)
    Jam's math problem(思维)
    77
    999
    888
    无 PowerShell.exe 执行 Empire 的几种姿势
  • 原文地址:https://www.cnblogs.com/wmj6/p/11288038.html
Copyright © 2011-2022 走看看