n rabbits were numbered form 1 to n. All rabbits' weight is an integer. For some unknown reason, two rabbits would fight each other if and only if their weight is NOT co-prime.
Now the king had arranged the n rabbits in a line ordered by their numbers. The king planned to send some rabbits into prison. He wanted to know that, if he sent all rabbits between the i-th one and the j-th one(including the i-th one and the j-th one) into prison, how many rabbits in the prison would not fight with others.
Please note that a rabbit would not fight with himself.
Input The input consists of several test cases.
The first line of each test case contains two integer n, m, indicating the number of rabbits and the queries.
The following line contains n integers, and the i-th integer W i indicates the weight of the i-th rabbit.
Then m lines follow. Each line represents a query. It contains two integers L and R, meaning the king wanted to ask about the situation that if he sent all rabbits from the L-th one to the R-th one into prison.
(1 <= n, m, W i <= 200000, 1 <= L <= R <= n)
The input ends with n = 0 and m = 0.
Output For every query, output one line indicating the answer.Sample Input
3 2 2 1 4 1 2 1 3 6 4 3 6 1 2 5 3 1 3 4 6 4 4 2 6 0 0
Sample Output
2 1 1 3 1 2
Hint
In the second case, the answer of the 4-th query is 2, because only 1 and 5 is co-prime with other numbers in the interval [2,6] .
题意:
给n个数,m次询问,每次询问一个区间,求该区间内有多少数与该区间其它数均互质。
首先,对于每一个数,都必存在一个最大的l和一个最小的r,满足下标在[l,r]区间内时与区间内所有其他数均互质。对于每次查询的区间,当且仅当[l,r]包含这个区间时,这个数才有贡献。
故我们可以考虑先预处理每个数的l和r,之后离线处理所有查询。先对所有查询按l从小到大,r从小到大的顺序排序,这样处理时就可以极大节省时间复杂度。
每次新查询的一个区间,就只需维护当前有多少符合条件的[l,r]区间。这只需要在上一次的基础上添加(add 1)和删除(add -1)即可。
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <queue> 8 #include <set> 9 #include <map> 10 #include <list> 11 #include <vector> 12 #include <stack> 13 #define mp make_pair 14 //#define P make_pair 15 #define MIN(a,b) (a>b?b:a) 16 //#define MAX(a,b) (a>b?a:b) 17 #define REP(I,N) for (I=0;I<N;I++) 18 #define rREP(I,N) for (I=N-1;I>=0;I--) 19 #define rep(I,S,N) for (I=S;I<N;I++) 20 #define rrep(I,S,N) for (I=N-1;I>=S;I--) 21 #define FOR(I,S,N) for (I=S;I<=N;I++) 22 #define rFOR(I,S,N) for (I=N;I>=S;I--) 23 typedef long long ll; 24 typedef unsigned long long ull; 25 const int MAX=2e5+5; 26 const int INF=1e7+5; 27 using namespace std; 28 //const int MOD=1e9+7; 29 typedef pair<ll,int> pii; 30 const double eps=0.00000001; 31 const int limit=2e5; 32 int n,m; 33 int c[MAX]; 34 inline int lowbit(int x) 35 { 36 return x&-x; 37 } 38 int presum(int x)//前缀和 39 { 40 int re=0; 41 while(x) 42 { 43 re+=c[x]; 44 x-=lowbit(x); 45 } 46 return re; 47 } 48 int sum(int l,int r) 49 { 50 return presum(r)-presum(l-1); 51 } 52 void add(int x,int d) 53 { 54 while(x<=n+1) 55 { 56 c[x]+=d; 57 x+=lowbit(x); 58 } 59 } 60 void init(int n) 61 { 62 int i; 63 FOR(i,1,n+1) c[i]=0; 64 } 65 struct node 66 { 67 int l,r,i; 68 }Q[MAX]; 69 int ans[MAX]; 70 bool cmp(node a,node b) 71 { 72 if(a.l!=b.l) 73 return a.l<b.l; 74 else 75 return a.r<b.r; 76 } 77 int prepos[MAX]; 78 int l[MAX],r[MAX]; 79 int a[MAX],b[MAX]; 80 vector<int>L[MAX]; 81 void solve() 82 { 83 int i,j,k; 84 FOR(i,1,n) scanf("%d",&a[i]),b[i]=a[i]; 85 memset(prepos,0,sizeof(prepos)); 86 FOR(i,1,n) 87 { 88 l[i]=1; 89 for(k=2;k*k<=a[i];k++) 90 { 91 if(a[i]%k==0) 92 { 93 l[i]=max(l[i],prepos[k]+1); 94 while(a[i]%k==0) 95 a[i]/=k; 96 prepos[k]=i; 97 } 98 } 99 if(a[i]>1) 100 { 101 k=a[i]; 102 l[i]=max(l[i],prepos[k]+1); 103 prepos[k]=i; 104 } 105 } 106 FOR(i,1,limit) prepos[i]=n+1; 107 rFOR(i,1,n) 108 { 109 r[i]=n; 110 for(k=2;k*k<=b[i];k++) 111 { 112 if(b[i]%k==0) 113 { 114 r[i]=min(r[i],prepos[k]-1); 115 while(b[i]%k==0) 116 b[i]/=k; 117 prepos[k]=i; 118 } 119 } 120 if(b[i]>1) 121 { 122 k=b[i]; 123 r[i]=min(r[i],prepos[k]-1); 124 prepos[k]=i; 125 } 126 } 127 FOR(i,1,n) vector<int>().swap(L[i]); 128 FOR(i,1,n) L[l[i]].push_back(i); 129 REP(i,m) scanf("%d%d",&Q[i].l,&Q[i].r),Q[i].i=i; 130 init(n); 131 sort(Q,Q+m,cmp); 132 int now1=0; 133 REP(i,m) 134 { 135 while(now1<Q[i].l) 136 { 137 if(now1) 138 add(now1,-1),add(r[now1]+1,1); 139 now1++; 140 for(int k:L[now1]) 141 { 142 add(k,1); 143 add(r[k]+1,-1); 144 } 145 } 146 ans[Q[i].i]=sum(Q[i].l,Q[i].r); 147 } 148 REP(i,m) printf("%d ",ans[i]); 149 } 150 int main() 151 { 152 while(scanf("%d%d",&n,&m)&&(n||m)) 153 solve(); 154 }