首页 > 代码库 > HDU5869树状数组+gcd预处理
HDU5869树状数组+gcd预处理
比赛的时候知道用树状数组,但有点乱不知道怎么处理。
统计不同的gcd的个数其实就是用树状数组统计区间内不同的数的模板题啊...
复杂度O(nlogn)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5+10; 4 int n,q,i,j,a[N],l[N],v[N]; 5 int fun(int x,int y){return __gcd(x,y);} 6 7 struct p{ 8 int l, r, ans, k; 9 };10 p query[N];11 bool cmp1(const p& a, const p& b){12 return a.r < b.r;13 }14 bool cmp2(const p& a, const p& b){15 return a.k < b.k;16 }17 18 int c[N], last[N*10], maxn;19 int lowbit(int x){ return x&-x;}20 void add(int x, int d){21 for(int i = x; i <= n; i += lowbit(i))22 c[i] += d;23 }24 int sum(int x){25 int ret = 0;26 while(x){27 ret += c[x];28 x -= lowbit(x);29 }30 return ret;31 }32 33 int main(){34 while(~scanf("%d%d", &n, &q)){35 maxn = -1;36 for(i = 1; i <= n; i++) scanf("%d", a+i), maxn = max(maxn, a[i]);37 for(i = 1; i <= q; i++){38 scanf("%d%d", &query[i].l, &query[i].r);39 query[i].k = i;40 }41 sort(query+1, query+q+1, cmp1);42 memset(last, 0, sizeof(int)*(maxn+5));43 memset(c, 0, sizeof(int)*(n+5));44 45 int qq = 1;46 for(i = 1; i <= n; i++){47 for(v[i] = a[i], j = l[i] = i; j; j = l[j]-1){48 v[j] = fun(v[j], a[i]);49 while(l[j] > 1&&fun(a[i], v[l[j]-1]) == fun(a[i], v[j])) l[j] = l[l[j]-1];50 //[l[j]..j,i]区间内的值求fun均为v[j]51 if(last[ v[j] ]){52 if(last[ v[j] ] < j){53 add(last[ v[j] ], -1);54 add(j, 1);55 last[ v[j] ] = j;56 }57 }58 else{//v[j] 没有59 add(j, 1);60 last[ v[j] ] = j;61 }62 }63 while(qq <= q&&query[qq].r == i){64 query[qq].ans = sum(query[qq].r) - sum(query[qq].l-1);65 qq++;66 }67 }68 sort(query+1, query+q+1, cmp2);69 for(int i = 1; i <= q; i++)70 printf("%d\n", query[i].ans);71 }72 }
HDU5869树状数组+gcd预处理
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。