Codeforces 703E Mishka and Divisors 离散化+DP
2017-08-15 17:59
302 查看
题意:给出长度为n的序列a,子序列合法:子序列中每个元素相乘后得到的乘积能被k整除
n<=1e3,k,a[i]<=1e12.找到长度最小的合法子序列(若长度最小的有多个,输出子序列和最小的)
设f[i][d]为 前i个数中选出乘积为d的倍数需要的最少个数.
f[i][d]=min(f[i-1][d],f[i-1][d/gcd(d,a[i])]+1) (f[i][x]<=f[i][px])
离散化第二维,因为d每次都转移到自己的某个因子中.最坏情况下只有6720个因子..
ps:
a[i]较大,令b[i]=gcd(a[i],k) 求gcd(a[i],v[j])时,将a[i]用b[i]代替不影响结果 (第一步只是排除掉a[i]中不含k素因子的因子).
n<=1e3,k,a[i]<=1e12.找到长度最小的合法子序列(若长度最小的有多个,输出子序列和最小的)
设f[i][d]为 前i个数中选出乘积为d的倍数需要的最少个数.
f[i][d]=min(f[i-1][d],f[i-1][d/gcd(d,a[i])]+1) (f[i][x]<=f[i][px])
离散化第二维,因为d每次都转移到自己的某个因子中.最坏情况下只有6720个因子..
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> ii; const int N=1e3+5; vector<ll> v; map<ll,int>id; ii f [8000]; ll n,k,m; void init() { v.clear(); for(ll i=1;i*i<=k;i++) { if(k%i==0) { v.push_back(i); if(i*i!=k) v.push_back(k/i); } } sort(v.begin(),v.end()); m=v.size()-1; id.clear(); for(int i=0;i<=m;i++) id[v[i]]=i; } ll a ,b ; ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } int main() { while(cin>>n>>k) { init(); for(int i=1;i<=n;i++) scanf("%I64d",&a[i]),b[i]=gcd(a[i],k); if(k==1) { puts("1"); printf("%d\n",min_element(a+1,a+1+n)-a); continue; } for(int j=1;j<=m;j++) f[0][j]=ii(n+1,0); for(int i=1;i<=n;i++) { for(int j=0;j<=m;j++) { f[i][j]=f[i-1][j]; int pre=id[v[j]/gcd(v[j],b[i])]; ii t=ii(f[i-1][pre].first+1,f[i-1][pre].second+a[i]); f[i][j]=min(f[i][j],t); } } if(f [m].first>n) puts("-1"); else { printf("%d\n",f [m].first); for(int i=n;i>=1;i--) { if(f[i][id[k]]!=f[i-1][id[k]]) { printf("%d ",i); k/=gcd(k,b[i]); } } } printf("\n"); } return 0; }
ps:
a[i]较大,令b[i]=gcd(a[i],k) 求gcd(a[i],v[j])时,将a[i]用b[i]代替不影响结果 (第一步只是排除掉a[i]中不含k素因子的因子).
相关文章推荐
- codeforces 703E Mishka and Divisors
- cf/codeforces #365 E - Mishka and Divisors 数学+背包dp+gcd
- Codeforces Round #365 (Div. 2)Mishka and Divisors 题解。 DP
- E. Mishka and Divisors Codeforces Round #365 (Div. 2) 01背包
- CodeForces 314 B.Sereja and Periods(dp)
- Codeforces 301D Yaroslav and Divisors 【树状数组 + 思维】
- CodeForces 771C Bear and Tree Jumps 树形DP
- Codeforces 766C Mahmoud and a Message 基础DP
- codeforces 713C C. Sonya and Problem Wihtout a Legend(dp)
- codeforces 467C George and Job(简单dp,看了题解抄一遍)
- Codeforces 518D Ilya and Escalator (概率dp)
- Codeforces 390C Inna and Candy Boxes RMQ简单变化 或 前缀和dp一下
- Codeforces 629 C Famil Door and Brackets(dp)
- codeforces 339C C. Xenia and Weights(dp)
- CodeForces 441 E.Valera and Number(概率DP)
- codeforces - 703A - Mishka and Game(水)
- 【codeforces 703 D】【离线询问 树状数组 前驱思想 前缀异或和】D. Mishka and Interesting sum【 区间内出现次数偶数的数的异或和】
- Codeforces 811C Vladik and Memorable Trip【Dp】
- CodeForces 482 D.Random Function and Tree(树形DP)
- Codeforces 467C George and Job(dp)