首页 > 代码库 > HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)
HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869
问你l~r之间的连续序列的gcd种类。
首先固定右端点,预处理gcd不同尽量靠右的位置(此时gcd种类不超过loga[i]种)。
预处理gcd如下代码,感觉真的有点巧妙...
1 for(int i = 1; i <= n; ++i) { 2 int x = a[i], y = i; 3 for(int j = 0; j < ans[i - 1].size(); ++j) { 4 int gcd = GCD(x, ans[i - 1][j].first); 5 if(gcd != x) { 6 ans[i].push_back(make_pair(x, y)); 7 x = gcd, y = ans[i - 1][j].second; 8 } 9 }10 ans[i].push_back(make_pair(x, y));11 }
然后用树状数组维护右端点固定的gcd位置。
1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime>10 #include <list>11 #include <set>12 #include <map>13 using namespace std;14 typedef long long LL;15 typedef pair <int, int> P;16 const int N = 1e6 + 5;17 int a[N/10 + 5], bit[N], _pos[N]; //_pos存的是gcd上一次出现的位置18 vector <P> ans[N/10 + 5]; //存的是以i为右端点的gcd19 struct query {20 int l, r, pos;21 bool operator <(const query& cmp) const {22 return r < cmp.r;23 }24 }q[N/10 + 5];25 int res[N/10 + 5]; //答案26 27 void init(int n) {28 memset(_pos, 0, sizeof(_pos));29 memset(bit, 0, sizeof(bit));30 for(int i = 1; i <= n; ++i) {31 ans[i].clear();32 }33 }34 35 int GCD(int a, int b) {36 return b ? GCD(b, a % b): a;37 }38 39 void add(int i, int x) {40 for( ; i <= N; i += (i&-i))41 bit[i] += x;42 }43 44 int sum(int i) {45 int s = 0;46 for( ; i >= 1; i -= (i&-i))47 s += bit[i];48 return s;49 }50 51 int main()52 {53 int n, m;54 while(scanf("%d %d", &n, &m) != EOF) {55 init(n);56 for(int i = 1; i <= n; ++i) {57 scanf("%d", a + i);58 }59 for(int i = 1; i <= m; ++i) {60 scanf("%d %d", &q[i].l, &q[i].r);61 q[i].pos = i;62 }63 for(int i = 1; i <= n; ++i) {64 int x = a[i], y = i;65 for(int j = 0; j < ans[i - 1].size(); ++j) {66 int gcd = GCD(x, ans[i - 1][j].first);67 if(gcd != x) {68 ans[i].push_back(make_pair(x, y));69 x = gcd, y = ans[i - 1][j].second;70 }71 }72 ans[i].push_back(make_pair(x, y));73 }74 sort(q + 1, q + m + 1);75 int p = 1;76 for(int i = 1; i <= n; ++i) {77 for(int j = 0; j < ans[i].size(); ++j) {78 if(!_pos[ans[i][j].first]) {79 add(ans[i][j].second, 1);80 _pos[ans[i][j].first] = ans[i][j].second;81 } else {82 add(_pos[ans[i][j].first], -1);83 _pos[ans[i][j].first] = ans[i][j].second;84 add(ans[i][j].second, 1);85 }86 }87 while(i == q[p].r && p <= m) {88 res[q[p].pos] = sum(q[p].r) - sum(q[p].l - 1);89 ++p;90 }91 }92 for(int i = 1; i <= m; ++i) {93 printf("%d\n", res[i]);94 }95 }96 return 0;97 }
HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。