想了半个多小时才发现原来和之前Codeforces div3的最后一题是一个题,于是写一遍加深印象
题面
给一个长度为
对数组进行多次查询,每次查询数组的一个连续区间
解
一开始以为是预处理,想了很久不知道怎么搞,想过st表,线段树,但感觉都做不了
突然发现后缀的
然后想到后缀gcd可能收敛的特别快,以至于可以改变复杂度
想了一下发现是log的速度,设目前的后缀gcd为
于是暴力就是对的
但是需要注意一下没有贡献的
而相等的一串是可以直接跳过去的,采用静态链表跳转,保证了复杂度是
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int long long
typedef unsigned long long ull;
#define dmp(x) cerr<<"DEBUG"<<__LINE__<<":"<<#x<<" "<<x<<endl
const ll INF=0x3f3f3f3f3f3f3f3fLL;
typedef pair<int,int> pii;
const int N=6e5+5;
int a[N],lt[N];
signed main() {
::sync_with_stdio(false);cin.tie(0);
iosint n,m;
>>n>>m;
cinfor(int i=1;i<=n;i++){
>>a[i];
cin}
for(int i=1;i<=n;i++)
[i]=i-1;
ltfor(int i=1;i<=n;i++){
if(a[i-1]%a[i]==0)
[i]=lt[i-1];
lt}
for(int i=1;i<=m;i++){
int l,r;
>>l>>r;
cinint ans=1,now=a[r];
for(int j=r;j>=l;j=lt[j]){
int tmp=__gcd(now,a[j]);
if(tmp!=now)
++;
ans=tmp;
nowif(now==1)
break;
}
<<ans<<'\n';
cout}
return 0;
}