题目:P7333 [JRKSJ R1] JFCA - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
分析:用rmq处理出各个区间长度的最大值,然后在二分区间长度找到答案
(最开始想的是开长度为n的数组,对位置i的数,分别找1-(i-1)和(i+1)-n中的离i最近满足条件的位置,然后更新结果,但一直wa,还没找到问题,存疑吧)
代码:
#include <bits/stdc++.h> using namespace std; #define ll long long #define endl '\n' using namespace std; typedef long double ld; typedef pair<int, int> pii; typedef pair<int,pair<int,ll>> pil; typedef unsigned long long ULL; const ll mod = 1e9+7; const int M=1e5+5; const int N = 1e5+ 5; ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } int cmp(int a, int b) { return a > b; } int n,a[N*3],b[N],f[N]; int dp[N*3][20]; void init() { for(int i=1;i<=3*n;i++) dp[i][0]=a[i]; for(int j=1;(1<<j)<=3*n;j++) { for(int i=1;i+(1<<j)-1<=3*n;i++) { dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } } } int query(int l,int r) { int k=log2(r-l+1); return max(dp[l][k],dp[r-(1<<k)+1][k]); } bool check(int x,int len,int v) { return max(query(x-len,x-1),query(x+1,x+len))>=v; } int work(int x,int v) { int l=1,r=n-1,ans=-1; while(l<r) { int mid=(l+r)/2; if(check(x,mid,v)) { ans=mid; r=mid; } else l=mid+1; } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; a[i+n]=a[i]; a[i+n*2]=a[i]; } for(int i=1;i<=n;i++) cin>>b[i]; init(); for(int i=1;i<=n;i++) { f[i]=work(i+n,b[i]); } for(int i=1;i<=n;i++) cout<<f[i]<<" "; }
一直wa的代码:
#include <bits/stdc++.h> using namespace std; #define ll long long #define endl '\n' using namespace std; typedef long double ld; typedef pair<int, int> pii; typedef pair<int,pair<int,ll>> pil; typedef unsigned long long ULL; const ll mod = 1e9+7; const int M=1e5+5; const int N = 1e5+ 5; ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } int cmp(int a, int b) { return a > b; } int n,a[N],b[N],f[N]; int dp[N][20]; // int n,a[N*3],b[N],f[N]; // int dp[N*3][20]; // void init() // { // for(int i=1;i<=3*n;i++) dp[i][0]=a[i]; // for(int j=1;(1<<j)<=3*n;j++) // { // for(int i=1;i+(1<<j)-1<=3*n;i++) // { // dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); // } // } // } void init() { for(int i=1;i<=n;i++) dp[i][0]=a[i]; for(int j=1;(1<<j)<=n;j++) { for(int i=1;i+(1<<j)-1<=n;i++) { dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } } } int query(int l,int r) { int k=log2(r-l+1); return max(dp[l][k],dp[r-(1<<k)+1][k]); } bool check(int x,int len,int v) { return max(query(x-len,x-1),query(x+1,x+len))>=v; } int work(int x,int v) { int l=1,r=x-1,ans1=-1,ans2=-1; while(l<=r) { int mid=(l+r)/2; if(query(x-mid,x-1)>=v){ ans1=mid; r=mid-1; } else l=mid+1; } ans1=min(ans1,n-ans1); l=1,r=n-x; while(l<=r) { int mid=(l+r)/2; if(query(x+1,x+mid)>=v) { ans2=mid; r=mid-1; } else l=mid+1; } ans2=min(ans2,n-ans2); if(ans1!=-1&&ans2!=-1) return min(ans1,ans2); else return max(ans1,ans2); // int l=1,r=n-1,ans=-1; // while(l<r) // { // int mid=(l+r)/2; // if(check(x,mid,v)) // { // ans=mid; // r=mid; // } // else l=mid+1; // } // return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; // a[i+n]=a[i]; // a[i+n*2]=a[i]; } for(int i=1;i<=n;i++) cin>>b[i]; init(); for(int i=1;i<=n;i++) { f[i]=work(i,b[i]); } for(int i=1;i<=n;i++) cout<<f[i]<<" "; }
标签:typedef,rmq,洛谷,int,ans1,ll,long,P7333,ans2 From: https://www.cnblogs.com/hhhhy0420/p/17318018.html