-
讲解
-
板子题
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n,m,l,r; int a[180010]; int maxn[180010][50]; int minn[180010][50]; /// f(i,j)=从ai开始的2^j个数里面 /// maxn[i][j]=[i,i+2^j-1]里面的最大值 int main() { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { scanf("%d",a+i); maxn[i][0]=a[i]; minn[i][0]=a[i]; } for(int j=1; j<=21; j++) { for(int i=1; (i+(1<<j)-1)<=n; i++) { maxn[i][j]=max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]); minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]); } } while(m--) { scanf("%d%d",&l,&r); int len=log2(r-l+1); int ans1=max(maxn[l][len],maxn[r-(1<<len)+1][len]);///len->2^(len-1) int ans2=min(minn[l][len],minn[r-(1<<len)+1][len]); // cout<<l<<" "<<r<<" "<<len<<" "<<maxn[l][len]<<" "<<maxn[r-(1<<len)+1][len]<<endl; printf("%d\n",ans1-ans2); } return 0; }
3.链接:https://ac.nowcoder.com/acm/contest/11256/K
来源:牛客网示例1
输入
5 1 1 2 3 4 5 2
输出
3
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #include <bits/stdc++.h> using namespace std; typedef long long ll; int n,m,k,a; int maxn[100005][30]; int minn[100005][30]; int lg[100005]; /// f(i,j)=从ai开始的2^j个数里面 /// maxn[i][j]=[i,i+2^j-1]里面的最大值 bool check(int l,int r,int k) { int len=lg[r-l+1]; int ans1=max(maxn[l][len],maxn[r-(1<<len)+1][len]);///len->2^(len-1) int ans2=min(minn[l][len],minn[r-(1<<len)+1][len]); if(ans1-ans2>k) return true; return false; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>m; for(int i=1; i<=n; i++) { cin>>a; maxn[i][0]=a; minn[i][0]=a; if(i>=2) lg[i]=lg[i/2]+1; } for(int j=1; j<=21; j++)///构造st表 { for(int i=1; (i+(1<<j)-1)<=n; i++) { maxn[i][j]=max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]); minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]); } } while(m--) { cin>>k; ll ans=0; for(int i=1,j=1; i<=n; i++) { while(!check(i,j,k)&&j>=i&&j<=n)///找最贴近的i { j++; } if(j<=n) { ans+=n-j+1; // printf("yes\n"); } } cout<<ans<<endl; } return 0; }
ST表——求区间[l,r]之间的最大值
最新推荐文章于 2024-05-31 11:08:33 发布