CF474F Ant colony(ST表+二分)
阿新 • • 發佈:2021-08-02
// Problem: CF474F Ant colony // Contest: Luogu // URL: https://www.luogu.com.cn/problem/CF474F // Memory Limit: 250 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll, ll>PLL; typedef pair<int, int>PII; typedef pair<double, double>PDD; #define I_int ll inline ll read() { ll x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-')f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } inline void out(ll x){ if (x < 0) x = ~x + 1, putchar('-'); if (x > 9) out(x / 10); putchar(x % 10 + '0'); } inline void write(ll x){ if (x < 0) x = ~x + 1, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } #define read read() #define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0) #define multiCase int T;cin>>T;for(int t=1;t<=T;t++) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i<(b);i++) #define per(i,a,b) for(int i=(a);i>=(b);i--) #define perr(i,a,b) for(int i=(a);i>(b);i--) ll ksm(ll a, ll b,ll p) { ll res = 1; while(b) { if(b & 1)res = res * a%p ; a = a * a %p; b >>= 1; } return res; } const int inf = 0x3f3f3f3f; const int maxn=1e5+7,maxm=210000; ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); } ll a[maxn],n,dp[maxn][32],b[maxn]; vector<int>g[maxn]; void init(){ rep(j,1,n) dp[j][0]=a[j]; for(int i=1;(1<<i)<=n;i++){ for(int j=1;j+(1<<i)-1<=n;j++){ dp[j][i]=gcd(dp[j][i-1],dp[j+(1<<(i-1))][i-1]); } } } ll query(int l,int r){ int k=(int)log2((r-l+1)); return gcd(dp[l][k],dp[r-(1<<k)+1][k]); } map<ll,ll>mp; int main(){ n=read; rep(i,1,n) a[i]=read,b[i]=a[i]; sort(b+1,b+1+n); int m=unique(b+1,b+1+n)-(b+1); rep(i,1,n){ int x=lower_bound(b+1,b+1+m,a[i])-b; mp[a[i]]=x; g[x].push_back(i); } init(); int q=read; while(q--){ int l=read,r=read; ll t=query(l,r); ll x=mp[t]; ll ans=upper_bound(g[x].begin(),g[x].end(),r)-upper_bound(g[x].begin(),g[x].end(),l-1); cout<<r-l+1-ans<<"\n"; } return 0; }