Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 40 Accepted Submission(s): 20
关键是在预处理,每个数预处理出L,R区间,表示左右和这个数不互质的位置。
这个只要从左到右和从右到左扫描一遍,分解质因素,找下一个质因素的位置。
然后对于每个查询进行离线处理,按照右端点排序。
遇到i,在L处+1, 遇到R,在i处+1,在L处-1.
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-9 14:38:41 4 File Name :E:\2013ACM\专题强化训练\区域赛\2013杭州\1008.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 21 const int MAXN = 200010; 22 int prime[MAXN+1]; 23 void getPrime() 24 { 25 memset(prime,0,sizeof(prime)); 26 for(int i = 2;i <= MAXN;i++) 27 { 28 if(!prime[i])prime[++prime[0]] = i; 29 for(int j = 1;j <= prime[0] && prime[j] <= MAXN/i;j++) 30 { 31 prime[prime[j]*i] = 1; 32 if(i % prime[j] == 0)break; 33 } 34 } 35 } 36 long long factor[100][2]; 37 int fatCnt; 38 int getFactors(long long x) 39 { 40 fatCnt = 0; 41 long long tmp = x; 42 for(int i = 1;prime[i] <= tmp/prime[i];i++) 43 { 44 factor[fatCnt][1] = 0; 45 if(tmp % prime[i] == 0) 46 { 47 factor[fatCnt][0] = prime[i]; 48 while(tmp % prime[i] == 0) 49 { 50 factor[fatCnt][1]++; 51 tmp /= prime[i]; 52 } 53 fatCnt++; 54 } 55 } 56 if(tmp != 1) 57 { 58 factor[fatCnt][0] = tmp; 59 factor[fatCnt++][1] = 1; 60 } 61 return fatCnt; 62 } 63 int L[MAXN],R[MAXN]; 64 int a[MAXN]; 65 int b[MAXN]; 66 int n,m; 67 int lowbit(int x) 68 { 69 return x & (-x); 70 } 71 int c[MAXN]; 72 void add(int i,int val) 73 { 74 if(i == 0)return; 75 while(i <= n) 76 { 77 c[i] += val; 78 i += lowbit(i); 79 } 80 } 81 int sum(int i) 82 { 83 int s = 0; 84 while(i > 0) 85 { 86 s += c[i]; 87 i -= lowbit(i); 88 } 89 return s; 90 } 91 vector<int>vec[MAXN]; 92 struct Node 93 { 94 int l,r; 95 int index; 96 void input() 97 { 98 scanf("%d%d",&l,&r); 99 } 100 }; 101 bool cmp(Node p1,Node p2) 102 { 103 return p1.r < p2.r; 104 } 105 Node node[MAXN]; 106 int ans[MAXN]; 107 int pp[MAXN][15]; 108 int main() 109 { 110 //freopen("in.txt","r",stdin); 111 //freopen("out.txt","w",stdout); 112 getPrime(); 113 while(scanf("%d%d",&n,&m) == 2) 114 { 115 if(n == 0 && m == 0)break; 116 for(int i = 1;i <= n;i++) 117 scanf("%d",&a[i]); 118 for(int i = 0;i < m;i++) 119 { 120 node[i].input(); 121 node[i].index = i; 122 } 123 for(int i = 1;i < MAXN;i++)b[i] = n+1; 124 for(int i = n;i >= 1;i--) 125 { 126 getFactors(a[i]); 127 R[i] = n+1; 128 pp[i][0] = fatCnt; 129 for(int j = 0;j < fatCnt;j++) 130 { 131 R[i] = min(R[i],b[factor[j][0]]); 132 b[factor[j][0]] = i; 133 pp[i][j+1] = factor[j][0]; 134 } 135 } 136 for(int i = 1;i < MAXN;i++)b[i] = 0; 137 for(int i = 1;i <= n;i++) 138 { 139 //getFactors(a[i]); 140 L[i] = 0; 141 fatCnt = pp[i][0]; 142 for(int j = 0;j < fatCnt;j++) 143 { 144 factor[j][0] = pp[i][j+1]; 145 L[i] = max(L[i],b[factor[j][0]]); 146 b[factor[j][0]] = i; 147 } 148 } 149 sort(node,node+m,cmp); 150 memset(c,0,sizeof(c)); 151 for(int i = 1; i <= n+1;i++) 152 { 153 c[i] = 0; 154 vec[i].clear(); 155 } 156 for(int i = 1;i <= n;i++)vec[R[i]].push_back(i); 157 int id = 1; 158 for(int i = 0;i < m;i++) 159 { 160 while(id <= n && id <= node[i].r) 161 { 162 add(L[id],1); 163 int sz = vec[id].size(); 164 for(int j = 0;j < sz;j++) 165 { 166 int v = vec[id][j]; 167 add(L[v],-1); 168 add(v,1); 169 } 170 id++; 171 } 172 ans[node[i].index] = sum(node[i].r) - sum(node[i].l-1); 173 ans[node[i].index] = node[i].r - node[i].l +1 - ans[node[i].index]; 174 } 175 for(int i = 0;i < m;i++)printf("%d\n",ans[i]); 176 177 178 } 179 return 0; 180 }