【题解】CF1156E Special Segments of Permutation
按最大值分治,判断最大值为当前这个数时的答案数,在左右区间中选择更小的区间,对于小区间的任意一个数判断另一个区间内是否含有,用 map 存下每个数的位置即可。
要特判递增和递减情况。
#include <bits/stdc++.h> #define ll long long // #define int ll #define ls a[p].l #define rs a[p].r #define re register #define pb push_back #define pir pair<int,int> #define f(a,x,i) for(int i=a;i<=x;i++) #define fr(a,x,i) for(int i=a;i>=x;i--) using namespace std; const int N=3e5+10; const int M=2e4+10; const int mod=1e9+7; mt19937 rnd(251); int n; int a[N]; ll ans=0; unordered_map<int,int> mp; void solve(int l,int r,int mx,int pos){ if(l==r||l>r){ return; } int mxl=0; int mxr=0; if(r-pos>=pos-l){ for(int i=l;i<=pos-1;i++){ int k=mp[mx-a[i]]; if(k>=pos+1&&k<=r){ ans++; } } } else{ for(int i=pos+1;i<=r;i++){ int k=mp[mx-a[i]]; if(k>=l&&k<=pos-1){ ans++; } } } if((pos-1)-l+1>1){ for(int i=l;i<=pos-1;i++){ mxl=max(mxl,a[i]); } solve(l,pos-1,mxl,mp[mxl]); } if(r-(pos+1)+1>1){ for(int i=pos+1;i<=r;i++){ mxr=max(mxr,a[i]); } solve(pos+1,r,mxr,mp[mxr]); } } signed main(){ // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); ios::sync_with_stdio(0); cin.tie(nullptr); int mx=0; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; mp[a[i]]=i; mx=max(mx,a[i]); } int op=1; for(int i=1;i<=n;i++){ if(a[i]!=i){ op=0; } } if(op==1){ cout<<0; return 0; } op=1; for(int i=1;i<=n;i++){ if(a[i]!=n-i+1){ op=0; } } if(op==1){ cout<<0; return 0; } solve(1,n,mx,mp[mx]); cout<<ans; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具