【题意】
给定N个数,M个查询,每个查询[L,R]内 与所有数互质的数的个数。所有数都小于200000.
【分析】
预处理第i个数,和他互质的数的区间[li,ri].因子分解从前往后和从后往前扫一遍即可求出。
然后问题就是求区间[L,R]被多少个[li,ri]{L<=i<=R}完全覆盖的问题了。
转化问题为求没有完全覆盖[L,R]的区间有多少个,做减法即可。
考虑区间相交的几种情况,判断哪些位置没有完全覆盖。用树状数组维护即可。
离线处理,把询问按照R排序。
未完待续。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <vector> 5 #include <algorithm> 6 7 using namespace std; 8 9 const int maxn = 200010; 10 int n, m; 11 12 struct BIT 13 { 14 int dt[maxn]; 15 void init() 16 { 17 memset(dt,0,sizeof dt); 18 } 19 int lowbit(int x) 20 { 21 return x&(-x); 22 } 23 24 void modify(int pos,int c) 25 { 26 if (pos<=0 || pos>n) return; 27 28 for (int x=pos; x<maxn; x+=lowbit(x)) 29 dt[x]+=c; 30 } 31 int query(int pos) 32 { 33 int res=0; 34 for (int x=pos; x>0; x-=lowbit(x)) 35 res+=dt[x]; 36 return res; 37 } 38 }bit; 39 40 41 42 struct query{ 43 int L,R; 44 int id; 45 46 bool operator < (const query &q)const{ 47 return R < q.R; 48 } 49 }que[maxn]; 50 bool cmp(query p, query q) 51 { 52 return p.R < q.R; 53 } 54 55 vector<int> fac[maxn]; 56 vector<int> sq[maxn]; 57 int a[maxn]; 58 int l[maxn]; 59 int r[maxn]; 60 int last[maxn]; 61 int ans[maxn]; 62 63 int main() 64 { 65 for (int i=1;i<maxn;i++){ 66 fac[i].clear(); 67 } 68 for (int i=2;i<maxn;i++){ 69 for (int j=i;j<maxn;j+=i){ 70 fac[j].push_back(i); 71 } 72 } 73 int cas; 74 while (scanf("%d%d", &n, &m)) 75 { 76 77 for (int i=1;i<=n;i++){ 78 sq[i].clear(); 79 } 80 81 if (n==0 && m==0) 82 break; 83 for (int i=1;i<=n;i++){ 84 scanf("%d", &a[i]); 85 } 86 memset(last, 0, sizeof(last)); 87 for (int i=1;i<=n;i++){ 88 int maxp = 0; 89 for (int j = 0;j<fac[a[i]].size();j++){ 90 maxp = max(maxp, last[fac[a[i]][j]]); 91 last[fac[a[i]][j]] = i; 92 } 93 l[i] = maxp + 1; 94 // printf("l = %d %d\n",i,l[i]); 95 } 96 memset(last, 0x3f3f3f, sizeof(last)); 97 for (int i=n;i>=1;i--){ 98 int minp = 0x3f3f3f; 99 for (int j=0;j<fac[a[i]].size();j++){ 100 minp = min(minp, last[fac[a[i]][j]]); 101 last[fac[a[i]][j]] = i; 102 } 103 minp = min(n+1, minp); 104 r[i] = minp - 1; 105 //printf("r = %d %d\n",i,r[i]); 106 } 107 for (int i=0;i<m;i++) 108 { 109 scanf("%d%d", &que[i].L, &que[i].R); 110 que[i].id = i; 111 } 112 sort(que, que+m); 113 114 int pos = 0; 115 bit.init(); 116 117 for (int i=1;i<=n && pos<m;i++){ 118 for (int j=0; j < sq[i].size();j++){ 119 bit.modify(sq[i][j], 1); 120 bit.modify(l[sq[i][j]]-1, -1); 121 } 122 bit.modify(l[i]-1, 1); 123 while (que[pos].R == i && pos < m) 124 { 125 int tmp = bit.query(que[pos].R) - bit.query(que[pos].L - 1); 126 127 ans[que[pos].id] = que[pos].R - que[pos].L + 1 - tmp; 128 pos++; 129 } 130 int tmp = r[i] + 1; 131 if (tmp <= n){ 132 sq[tmp].push_back(i); 133 } 134 } 135 for (int i=0;i<m;i++) 136 { 137 printf("%d\n",ans[i]); 138 } 139 } 140 return 0; 141 }