D. Pair of Numbers (ST表&二分&双指针)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D. Pair of Numbers (ST表&二分&双指针)相关的知识,希望对你有一定的参考价值。
D. Pair of Numbers (ST表&二分&双指针)
显然就是找最大区间 g c d = m i n gcd=min gcd=min ,且长度具有二分性,然后没了,代码懒得写,参考的题解区。
#include <stdio.h>
inline int read()
{
int num=0;char c=getchar();
while(c<48||c>57)c=getchar();
while(c>47&&c<58)num=num*10+(c^48),c=getchar();
return num;
}
inline int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
inline int lcm(int a,int b)
{
return a>b?b:a;
}
int st[300005][23],log2[300005],mn[300005][23];
inline int queryG(int a,int b)
{
int k=log2[b-a+1]-1;
return gcd(st[a][k],st[b-(1<<k)+1][k]);
}
inline int queryL(int a,int b)
{
int k=log2[b-a+1]-1;
return lcm(mn[a][k],mn[b-(1<<k)+1][k]);
}
int ans,qaqaqaq[300005];
inline int qaq(int qwq,int n)
{
int a=0;
for(int i=1;i+qwq<=n;i++)
{
if(queryG(i,i+qwq)==queryL(i,i+qwq))qaqaqaq[a++]=i;
}
if(a)return ans=a;
else return 0;
}
int main()
{
int n=read();
for(int i=1;i<=n;i++)st[i][0]=mn[i][0]=read(),log2[i]=log2[i>>1]+1;
for(int i=1;i<=22;i++)
for(int j=1;j+(1<<i)-1<=n;j++)st[j][i]=gcd(st[j][i-1],st[j+(1<<i-1)][i-1]),mn[j][i]=lcm(mn[j][i-1],mn[j+(1<<i-1)][i-1]);
int l=0,r=n-1,qwq=114514;
while(l<=r)
{
int m=l+(r-l>>1);
if(qaq(m,n))l=m+1,qwq=m;
else r=m-1;
// printf("D %d %d\\n",l,r);
}
printf("%d %d\\n",ans,qwq);
for(int i=0;i<ans;i++)printf("%d ",qaqaqaq[i]);
return 0;
}
这里主要讲下类似双指针的做法。
我们可以枚举那个最小值 a i a_i ai,然后两个指针 l , r l,r l,r 往两边走,每次取最大值。
然后 i i i 移动到 r + 1 r+1 r+1 ,这样总复杂度最多 O ( 2 n ) O(2n) O(2n)
为什么呢?
考虑如上图 a i a_i ai 的最大范围是 [ L , R ] [L,R] [L,R] ,对于点 A A A ,能整除 A A A 的点,必然能整除 a i a_i ai ,所以 A A A的右端点 R A R_A RA 不会超过 R R R ,但是左端点最多是 i + 1 i+1 i+1 。
所以显然长度更劣,不会对答案有贡献, A A A在 a i a_i ai 左端点同理。
因此 i i i 可以跳到 R + 1 R+1 R+1。
// Problem: D. Pair of Numbers
// Contest: Codeforces - Codeforces Round #209 (Div. 2)
// URL: https://codeforces.ml/contest/359/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Date: 2021-08-04 16:23:27
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=3e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int a[N],b[N],ans,cnt;
int main(){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1,l,r;i<=n;){
l=r=i;
while(l-1>0&&a[l-1]%a[i]==0) l--;
while(r+1<=n&&a[r+1]%a[i]==0) r++;
i=r+1;
r-=l;
if(r>ans) ans=r,cnt=0;
if(r==ans) b[++cnt]=l;
}
printf("%d %d\\n",cnt,ans);
for(int i=1;i<=cnt;i++) printf("%d ",b[i]);printf("\\n");
return 0;
}
以上是关于D. Pair of Numbers (ST表&二分&双指针)的主要内容,如果未能解决你的问题,请参考以下文章
Eming cup Problem D. Game of numbers
Codeforces Round #627 (Div. 3) D. Pair of Topics(二分/直接遍历)
D. Arpa and a list of numbers Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017)(示