預處理求區間[l,r]的gcd,固定r向左
如[1,3]->[3,3]->[2,3]->[1,2,3]這樣才保證了求出了所有的區間內所有的gcd
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Arrays;
public class Main_HDU5869 {
static ArrayList<node5869_>[] gcd = new ArrayList[100005];
static int n,q;
static int[] ans = new int[100005];
static int[] a = new int[100005];
static node5869[] node = new node5869[100005];
static int[] vis = new int[1000005];
static int[] sum = new int[1000005];
public static void main(String[] args) throws IOException {
StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(System.out);
for(int i=0;i<=100000;i++) {
gcd[i] = new ArrayList<node5869_>();
}
while(sc.nextToken()!=StreamTokenizer.TT_EOF) {
n = (int)sc.nval;
sc.nextToken();
q = (int)sc.nval;
for(int i=1;i<=n;i++) {
sc.nextToken();
a[i] = (int)sc.nval;
gcd[i].clear();
}
for(int i=1,j;i<=n;i++) { //預處理求區間gcd 固定r向左求出每個區間的gcd種類 如求[1,3]->[3,3]->[2,3]->[1,2,3]
int t = a[i];
int len = gcd[i-1].size();
gcd[i].add(new node5869_(i,a[i])); //gcd[i] 表示以i結尾的每個區間gcd
for(j=0;j<len;j++) {
int tgcd = gcd(t,gcd[i-1].get(j).gcd);
int pos = gcd[i-1].get(j).i;
if(tgcd!=t) { //去掉所求區間重複的gcd
gcd[i].add(new node5869_(pos,tgcd));
t = tgcd;
}
}
}
for(int i=1;i<=q;i++) {
sc.nextToken();
int l = (int)sc.nval;
sc.nextToken();
int r = (int)sc.nval;
node[i] = new node5869(l,r,i);
}
Arrays.sort(node,1,1+q);
Arrays.fill(vis, 0);
Arrays.fill(ans, 0);
Arrays.fill(sum, 0);
int k = 1;
for(int i=1;i<=n;i++) {
int len = gcd[i].size();
for(int j=0;j<len;j++) {
if(vis[gcd[i].get(j).gcd]!=0) { //說明該gcd前面出現過 vis存放的是該gcd上一次出現的位置
update(vis[gcd[i].get(j).gcd],-1);
}
vis[gcd[i].get(j).gcd] = gcd[i].get(j).i;
update(gcd[i].get(j).i,1);
}
while(k<=q&&node[k].r<=i) {
ans[node[k].id] = getsum(node[k].r)-getsum(node[k].l-1);
k++;
}
}
for(int i=1;i<=q;i++) {
out.println(ans[i]);
}
out.flush();
}
}
public static int gcd(int a,int b) {
if(b==0) return a;
else return gcd(b,a%b);
}
public static void update(int x,int d) {
for(int i=x;i<=n;i+=i&(-i)) {
sum[i] += d;
}
}
public static int getsum(int x) {
int ans = 0;
for(int i=x;i>=1;i-=i&(-i)) {
ans += sum[i];
}
return ans;
}
}
class node5869 implements Comparable<node5869>{
int l,r,id;
public node5869(int l,int r,int id) {
this.l = l;
this.r = r;
this.id = id;
}
@Override
public int compareTo(node5869 o) {
return this.r-o.r;
}
}
class node5869_{
int i,gcd;
public node5869_(int i,int gcd) {
this.i = i;
this.gcd = gcd;
}
}