HDU 4777 树状数组求区间内 与该区间都互质的数个数

来源:互联网 发布:子域名共享session php 编辑:程序博客网 时间:2024/05/16 14:04

题意:

给定n个数的序列

m个询问,问该区间内,与所有区间内数互质的数有多少个

 

#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>#include<math.h>#define N 200005using namespace std;vector<int>prime[N];//prime[i] 是i的所有因子(不包括1)vector<int>edge[N];struct query{int l, r, num;bool operator<(const query& a)const{return a.l>l;}}q[N];int ans[N];int tree[N];int l[N], r[N], vis[N];int n, m, a[N];int lowbit(int x){return x&(-x);}void add(int pos, int val){while(pos){tree[pos] += val;pos -= lowbit(pos);}}int getsum(int pos){int ans = 0;while(pos <= n){ans += tree[pos];pos += lowbit(pos);}return ans;}void init(){for(int i = 2; i < N; i++)for(int j = i; j < N; j+=i)prime[j].push_back(i);}int main(){int i, j;init();while(scanf("%d %d",&n,&m), n+m){for(i = 1; i <= n; i++)scanf("%d",&a[i]);memset(vis, 0, sizeof(vis));for(i = 1; i <= n; i++){int pos = 0, siz = prime[a[i]].size();for(j = 0; j < siz; j++){pos = max(pos, vis[prime[a[i]][j]]);vis[prime[a[i]][j]] = i;}l[i] = pos;}memset(vis, 1, sizeof(vis));for(i = n; i ; i--){int pos = n+1, siz = prime[a[i]].size();for(j = 0; j < siz; j++){pos = min(pos, vis[prime[a[i]][j]]);vis[prime[a[i]][j]] = i;}r[i] = pos;}memset(tree, 0, sizeof(tree));for(i = 1; i <= n; i++){if(l[i])edge[l[i]].push_back(i);else{add(i, 1);if(r[i]<=n)add(r[i], -1);}}for(i = 1; i <= m; i++)scanf("%d %d",&q[i].l,&q[i].r), q[i].num = i;sort(q+1, q+m+1);int num = 1;for(i = 1; i <= n; i++){while(q[num].l == i){ans[q[num].num] = getsum(q[num].l) - getsum(q[num].r+1);num++;}add(i, -1);if(r[i] <= n)add(r[i], 1);for(j = 0; j < edge[i].size(); j++){int v = edge[i][j];add(v, 1);if(r[v]<=n)add(r[v], -1);}edge[i].clear();}for(i = 1; i<= m; i++)printf("%d\n", ans[i]);}return 0;}


 

0 1
原创粉丝点击