【rmq】洛谷P7333
题目: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]<<" "; }
分类:
数据结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话