hdu 6025
来源:互联网 发布:mac粉底液哪个最白 编辑:程序博客网 时间:2024/06/05 03:50
题意:在数列中删除一个数使得所有数的gcd最大;
思路:
1.用一个前缀数组gd1[]记录前i个数的gcd,一个后缀数组gd2[]记录后i ~ n个数的gcd,当要删除第i个数的时候,数列的gcd为gcd(gd1[i - 1],gd2[i + 1]);
为了使得能删除第一个数和最后一个数,增加了a[0] = a[n + 1] = 0;因为gcd(0,x) == x;
2.当然也可以用线段树进行操作,记录的值为它的线段的gcd,删除基理一样,查询前i- 1的gcd,和i+1之后区间的gcd,然后取gcd;
前缀数组:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<vector>#include<map>#include<string>using namespace std;#define clr(x,y) memset(x,y,sizeof x)const int maxn = 100000 + 10;const double pp = 10e8;typedef long long ll;const ll SMod = 1000000007;int gcd(int x,int y){ return y ? gcd(y,x % y) : x;}int n,m;int a[maxn];int gd1[maxn];int gd2[maxn];int main(){ int Tcase; scanf("%d",&Tcase); while(Tcase --)// while( ~ scanf("%I64d%I64d",&n,&m)) { scanf("%d",&n); for(int i = 1; i <= n; i ++) scanf("%d",&a[i]); gd1[0] = gd2[n + 1] = 0; for(int i = 1; i <= n; i ++) { gd1[i] = gcd(gd1[i - 1],a[i]); } for(int i = n; i >= 1; i --) { gd2[i] = gcd(gd2[i + 1],a[i]); } int ans = 1; for(int i = 1; i <= n; i ++) { ans = max(ans,gcd(gd1[i - 1],gd2[i + 1])); } printf("%d\n",ans); } return 0;}
线段树:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<vector>#include<algorithm>using namespace std;const int maxn = 100000 + 10;#define INF 0x3f3f3f3f#define clr(x,y) memset(x,y,sizeof x )typedef long long ll;#define eps 10e-10const ll Mod = 1000000007;struct Tree{ int l; int r; int gd;}tree[maxn<<2];int gcd(int x,int y){ return y ? gcd(y,x % y) : x;}int a[maxn];void build(int rt,int l,int r){ tree[rt].l = l; tree[rt].r = r; if(l == r) { tree[rt].gd = a[l]; return ; } int mid = (l + r) >> 1; build(rt << 1,l,mid); build(rt<< 1 | 1,mid+1,r); tree[rt].gd = gcd(tree[rt << 1].gd,tree[rt << 1 | 1].gd);}int query(int rt,int L,int R){ if(tree[rt].l >= L&& tree[rt].r <= R) { return tree[rt].gd; } int mid = (tree[rt].l + tree[rt].r) >> 1; int ret = 0; if(L <= mid) { ret = gcd(ret,query(rt<<1,L,R)); } if(R >= mid + 1) ret =gcd(ret,query(rt << 1 | 1,L,R)); return ret;}int main(){ int Tcase; scanf("%d",&Tcase); while(Tcase --) { int n; scanf("%d",&n); for(int i = 1; i <= n; i ++) scanf("%d",&a[i]); a[0] = a[n + 1] = 0; build(1,0,n + 1); int ans = 0; for(int i = 1; i <= n; i ++) { ans = max(ans,gcd(query(1,0,i - 1),query(1,i + 1,n + 1))); } printf("%d\n",ans); } return 0;}
RMQ:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<vector>#include<algorithm>using namespace std;const int maxn = 100000 + 10;#define INF 0x3f3f3f3f#define clr(x,y) memset(x,y,sizeof x )typedef long long ll;#define eps 10e-10const ll Mod = 1000000007;int a[maxn];int dp[maxn][31];int n;int gcd(int x,int y){ return y ? gcd(y,x % y) : x;}void RMQ_Init(){ for(int i = 0; i <= n + 1; i ++) { dp[i][0] = a[i]; } for(int j = 1; (1 << j) <= n + 1;j ++) { for(int i = 0; i + (1 << j) - 1 <= n + 1; i ++) { dp[i][j] = gcd(dp[i][j - 1],dp[i + (1 << (j - 1))][j - 1]); } }}int query(int l,int r){ int k = 0; while((1 << (k + 1)) <= (r - l + 1)) k ++; return gcd(dp[l][k],dp[r - (1 << k) + 1][k]);}int main(){ int Tcase; scanf("%d",&Tcase); while(Tcase --) { scanf("%d",&n); for(int i = 1; i <= n; i ++) scanf("%d",&a[i]); RMQ_Init();// int ans = max(query(2, n), query(1, n - 1)); int ans = 0; for(int i = 1; i <= n; i ++) {// cout << gcd(query(0, i - 1),query(i + 1, n + 1)) << endl; ans = max(ans, gcd(query(0, i - 1),query(i + 1, n + 1))); } printf("%d\n",ans); } return 0;}
0 0
- hdu 6025
- hdu 6025
- HDU 6025 Coprime Sequence
- HDU 6025 Coprime Sequence
- hdu 6025 Coprime Sequence
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- Discuz!论坛教程之批量修改用户组的方法
- TCL一个雷鸟,或是互联网电视的最后一声惊雷
- VisualSVN server修改钩子支持编辑日志
- 将博客搬至CSDN
- 探索文件描述符(fd)与FILE结构体之间的关系
- hdu 6025
- 静态分析工具
- Openjudge 1.11 09:膨胀的木棍
- 51nod 1083 矩阵取数问题(基础dp)
- Apache ERROR: No space left on device: AH00023: Couldn't create the ssl-cache mutex
- SVN的配置和使用
- dojo中的dojoConfig配置
- 【Linux】-- 环境变量 path 的查看、添加及删除
- CWE -- Out-of-bounds Write 例子