CF359D-Pair of Numbers
题目大意
你有一个数组 \(a\) ,包含 \(n\) 个数字。你要找到一对整数对,使得
· 存在整数 \(j\) ,\((l \le j \le r),\) \(a_l,…,a_r\)
· 值 \(r-l\) 取到最大值
找出所有对应 \(r-l\) 最大值的 \(l\) 位置。
\(Hint\)
考虑怎样的区间 \([l,r]\) 能满足上述条件。不难发现是 区间 \(gcd\) 等于 区间 \(min\) 。
题解
对于 \(r-l\) 的值,考虑二分答案。
接下来对于每一个 \(i\) ,判断其 \([i,i+r-l]\) 区间 \(gcd\) 等于 区间 \(min\) 。用 \(st\) 表维护静态区间 \(gcd\) 和 \(min\)。记录满足条件的位置。
#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define umap unordered_map
#define endl '\n'
using namespace std;
using i128 = __int128;
const int mod =1e9+7;
template <typename T>void read(T&x){
x=0;int f = 1;
char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
x*=f;
}
template <typename T>void print(T x) {
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
#define int long long
const int maxn=3e5+10;
int a[maxn],dp[maxn][22],dpgcd[maxn][22];
void stmin(int n)
{
for (int i=1;i<=n;i++)
dp[i][0]=a[i];
for (int j=1;j<=21;j++)
for (int i=1;i+(1<<j)-1<=n;i++)
dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int querymin(int l,int r)
{
int k=log2(r-l+1);
return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
void stgcd(int n)
{
for (int i=1;i<=n;i++)
dpgcd[i][0]=a[i];
for (int j=1;j<=21;j++)
for (int i=1;i+(1<<j)-1<=n;i++)
dpgcd[i][j]=gcd(dpgcd[i][j-1],dpgcd[i+(1<<(j-1))][j-1]);
}
int querygcd(int l,int r)
{
int k=log2(r-l+1);
return gcd(dpgcd[l][k],dpgcd[r-(1<<k)+1][k]);
}
const int N=500005;
const int M=2000005;
inline void solve()
{
vector<int> ans;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
stmin(n);stgcd(n);
int l=0,r=n;
while(l<r)
{
vector<int> temp;
int mid=l+r+1>>1;
for(int i=1;i+mid<=n;i++)
{
if(querymin(i,i+mid)==querygcd(i,i+mid))
{
temp.push_back(i);
}
}
if(temp.size()==0)
{
r=mid-1;
}
else
{
l=mid;
ans=temp;
}
}
if(l==0)
{
cout<<n<<" "<<0<<endl;
for(int i=1;i<=n;i++) cout<<i<<" ";
return;
}
cout<<ans.size()<<" "<<l<<endl;
for(int i=0;i<ans.size();i++)
{
cout<<ans[i]<<" ";
}
cout<<endl;
}
signed main()
{
// ios;
int T=1;
// cin>>T;
for(;T--;) solve();
return 0;
}

浙公网安备 33010602011771号