luogu P4755 Beautiful Pair - 启发式合并 - 主席树

探讨了如何解决一个特定的算法问题,即在给定的非负整数数列中,找出所有满足条件的子区间,使得端点权值乘积小于等于区间最大值。文章详细介绍了使用启发式分裂方法的解决方案,并提供了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:
给一个非负整数数列,问有多少子区间,端点权值乘积小于等于区间最大值。
(其实是启发式分裂?
这个题做法一模一样,没了。

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define mod 998244353
#define N 100010
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
    int x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
pii b[N];vector<int> v;int L[N],R[N],st[N],m,a[N],zo[N];set<int> s;
inline bool cmp(pii a,pii b) { return a.fir!=b.fir?a.fir>b.fir:a.sec<b.sec; }
inline int getid(int x) { return lower_bound(v.begin(),v.end(),x)-v.begin()+1; }
struct segment{
    int s;segment *ch[2];
}*T[N];
int build(segment* &rt,int l,int r)
{
    rt=new segment,rt->s=0;int mid=(l+r)>>1;if(l==r) return 0;
    return build(rt->ch[0],l,mid),build(rt->ch[1],mid+1,r);
}
int update(segment* &x,segment* &y,int p,int l,int r)
{
    x=new segment,x->ch[0]=y->ch[0],x->ch[1]=y->ch[1];
    x->s=y->s+1;if(l==r) return 0;int mid=(l+r)>>1;
    if(p<=mid) update(x->ch[0],y->ch[0],p,l,mid);
    else update(x->ch[1],y->ch[1],p,mid+1,r);return 0;
}
int query(segment* &x,segment* &y,int s,int t,int l,int r)
{
    if(s<=l&&r<=t) return x->s-y->s;int mid=(l+r)>>1,ans=0;
    if(s<=mid) ans+=query(x->ch[0],y->ch[0],s,t,l,mid);
    if(mid<t) ans+=query(x->ch[1],y->ch[1],s,t,mid+1,r);
    return ans;
}
inline int query(int L,int R,int s,int t)
{
    if(L>R||s>t) return 0;
    if(R-L<=40) { int ans=0;rep(i,L,R) ans+=(a[i]>=s&&a[i]<=t);return ans; }
    int x=getid(s),y=getid(t);
    if(v[y-1]>t) y--;if(x>y) return 0;
    return query(T[R],T[L-1],x,y,1,m);
}
int main()
{
    //freopen("data.in","r",stdin),freopen("std.out","w",stdout);
    int n=inn();rep(i,1,n) a[i]=inn(),v.pb(a[i]);
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    m=(int)v.size(),build(T[0],1,m);
    rep(i,1,n) update(T[i],T[i-1],getid(a[i]),1,m);
    rep(i,1,n) L[i]=1,R[i]=n;lint ans=0;
    for(int i=1,t=0;i<=n;st[++t]=i++)
        while(t&&a[st[t]]<a[i]) R[st[t--]]=i-1;
    for(int i=n,t=0;i>=1;st[++t]=i--)
        while(t&&a[st[t]]<=a[i]) L[st[t--]]=i+1;
    rep(i,1,n) zo[i]=zo[i-1]+(a[i]<=1);
    s.insert(0),s.insert(n+1);
    rep(i,1,n) b[i]=mp(a[i],i);
    sort(b+1,b+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        int x=b[i].sec,L,R;
        sit it=s.lower_bound(x);
        R=(*it)-1,it--,L=(*it)+1;
        if(a[x]) ans+=zo[R]-zo[L-1];
        else ans+=R-L+1;
        int Llen=x-L,Rlen=R-x;
        if(Llen<=Rlen) rep(j,L,x-1) ans+=(a[j]?query(x+1,R,0,a[x]/a[j]):Rlen);
        else rep(j,x+1,R) ans+=(a[j]?query(L,x-1,0,a[x]/a[j]):Llen);
        s.insert(x);
    }
    return !printf("%lld\n",ans);
}
内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值