GCD
来源:互联网 发布:单片机培训机构 编辑:程序博客网 时间:2024/05/16 00:36
GCD
.
.
题意:给n个数,q次询问,问l到r之间的数的gcd的值为多少,并输出序列中所有(l<=r)的子序列中,有多少对的gcd值为询问的值
.
.
解法:因为数越多,gcd值的数越小,可以用map先预处理第二问,然后第一问可以用线段树处理。
.
.
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <map>#include <string.h>using namespace std;int tree[2500000], n, m, t, x, y, k;map<int, long long> f[200000], ans;int gcd(int x, int y) { while (1) { int temp = x%y; x = y; y = temp; if (y == 0) break; } return x;}void insert(int x, int l, int r, int pos, int val) { if (l == r) { tree[x] = val; return; } int mid = (l+r)>>1; if (pos <= mid) { insert(x<<1, l, mid, pos, val); if (tree[x] == 0) tree[x] = tree[x<<1]; else tree[x] = gcd(tree[x], tree[x<<1]); } else { insert(x<<1|1, mid+1, r, pos, val); if (tree[x] == 0) tree[x] = tree[x<<1|1]; else tree[x] = gcd(tree[x], tree[x<<1|1]); }}int find(int x, int l, int r, int ll, int rr) { if (l == ll && r == rr) { return tree[x]; } int mid = (l+r)>>1; if (rr <= mid) { int temp = find(x<<1, l, mid, ll, rr); return temp; } else if (ll >= mid+1) { int temp = find(x<<1|1, mid+1, r, ll, rr); return temp; } else { int temp1 = find(x<<1, l, mid, ll, mid); int temp2 = find(x<<1|1, mid+1, r, mid+1, rr); return (gcd(temp1, temp2)); }}int main() { freopen("d.in","r",stdin); int tt; scanf("%d", &tt); int cases = 0; while (tt--) { cases++; scanf("%d", &n); ans.clear(); memset(tree, 0, sizeof(tree)); for (int i = 1; i <= n; i++) { scanf("%d", &x); insert(1, 1, n, i, x); f[i].clear(); f[i][x] = 1; if (!ans[x]) ans[x] = 1; else ans[x] = ans[x]+1; if (i != 1) for (map<int, long long>::iterator ii = f[i-1].begin(); ii != f[i-1].end(); ii++) { int temp = gcd(ii->first, x); if (!f[i][temp]) f[i][temp] = f[i-1][ii->first]; else f[i][temp] = f[i][temp]+f[i-1][ii->first]; if (!ans[temp]) ans[temp] = f[i-1][ii->first]; else ans[temp] = ans[temp]+f[i-1][ii->first]; } } /* for (int i = 1; i <= n; i++) { printf("%d : \n", i); for (map<int, long long>::iterator ii = f[i].begin(); ii != f[i].end(); ii++) { printf("\t%d %lld\n", ii->first, ii->second); } } */ printf("Case #%d:\n", cases); scanf("%d", &m); for (int i = 1; i <= m; i++) { scanf("%d %d", &x, &y); if (x > y) swap(x, y); t = find(1, 1, n, x, y); printf("%d %lld\n", t, ans[t]); } }}
0 0
- gcd
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- gcd
- GCD
- GCD
- GCD
- GCD
- GCD
- 内核3.x版本之后设备树机制
- Qt4.8.6 ARM(DM3730)中文显示,文泉驿正黑
- [USACO Training] Section 2.3
- 第9课 Go接口interface
- Java笔记之数组
- GCD
- javascript 简单介绍
- Android Gradle 配置小窥
- 找出字符串中第一个只出现一次的字符
- nginx之第一个helloworld程序
- 找女朋友
- 使用ffmpeg 对视频做resize
- ActiveMq的简单使用
- C++强制转换运算符