zoukankan      html  css  js  c++  java
  • 笛卡尔积

    https://ac.nowcoder.com/acm/contest/883/G

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define LL long long
    const int maxn=3e5+5;
    int a[maxn];
    int rt,ls[maxn],rs[maxn];
    int top;
    int sta[maxn];
    int fa[maxn];
    
    int build(int n) //笛卡尔树 大顶堆
    {
        top=0;
        for(int i=1;i<=n;i++)
        {
            while(top&&a[sta[top-1]]<a[i])top--; //小数都出栈
            if(!top) //栈空 i点作右上父亲
            {
                int t=sta[0];
                fa[t]=i;
                ls[i]=t;
            }
            else //i点可做右孩子
            {
                int t=sta[top-1];
                if(rs[t]){
                    ls[i]=rs[t];
                    fa[rs[t]]=i;
                }
                fa[i]=t;
                rs[t]=i;
            }
            sta[top++]=i;
        }
        return sta[0]; //根结点
    
    }
    
    LL pre[maxn];
    void dfs(int rt,int l,int r,LL &ans){
        if(l>=r)return;
        if(rt-l<r-rt){
            // 找右边第一个可以的位置
            rep(i,l,rt){
                int pos=lower_bound(pre+rt,pre+r+1,pre[i-1]+2ll*a[rt])-pre;
    //            if(pos==i)pos++;
    //            if(pos==r+1)continue;
                ans+=(LL)(r-pos + 1);
            }
        }
        else{
            rep(i,rt,r){
                // 找左边第一个不行的位置
                int pos=upper_bound(pre+l,pre+rt,pre[i]-2ll*a[rt])-pre;
                if(pre[i]-pre[pos-1]>=2*a[rt]) pos++;
                pos=min(pos,rt+1);
                ans += (LL)(pos - (l - 1));
    //            ans+=max(0,pos-l);
            }
        }
    
        dfs(ls[rt],l,rt-1,ans);
        dfs(rs[rt],rt+1,r,ans);
    }
    
    int main(){
        int t;scanf("%d",&t);
        while(t--){
            int n;scanf("%d",&n);
            rep(i,1,n){
                scanf("%d",&a[i]);
                pre[i]=pre[i-1]+1ll*a[i];
            }
            rt = build(n);
            LL ans=0;
            dfs(rt,1,n,ans);
            printf("%lld
    ",ans);
        }
    }
  • 相关阅读:
    Ubuntu中的vsftpd配置
    Ubuntu学习-增加更新源及安装软件及卸载软件
    Ubuntu16.04下安装sublime text3
    需要读的书
    同一机器 部署 两个 jboss
    log4j 总结 精华
    oracle 笔记
    oracle 用户 多个表空间
    json
    json 基础
  • 原文地址:https://www.cnblogs.com/downrainsun/p/11262230.html
Copyright © 2011-2022 走看看