http://codeforces.com/contest/494/problem/D

题意:给一个数组,和一个坏质数集合,可以无数次地让1到i这些所有数字除以他们的gcd,然后要求Σf(a[i])的最大值,其中

f(x)=f(x/p)+1,p为x的最小质数,且p不为坏质数

f(x/p)-1 ,p为x的最小质数,且p为坏质数

思路:我们考虑,如果f[j]取了1到j的gcd,那么对后面的决策并没有任何影响,因为我们统计的贡献,只统计1到i这个部分,不统计i以后的部分。

略坑,不知道第一次被什么卡了超时。。就写哈希了。。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<map>
 7 #include<set>
 8 std::map<int,int>mp;
 9 std::set<int>b;
10 int n,m,f[200005],g[200005],a[200005];
11 int read(){
12     char ch=getchar();int t=0,f=1;
13     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
14     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
15     return t*f;
16 }
17 int gcd(int a,int b){
18     if (b==0) return a;
19     else return gcd(b,a%b);
20 }
21 int F(int x){
22     if (x<=1) return 0;
23     if (b.count(x)) return -1;
24     int rec=x,res=0;
25     if (mp.find(rec)!=mp.end()) return mp[rec];
26     int d=0,cnt=0;
27     for (int i=2;i*i<=rec;i++){
28         int p=i;
29         if (x%p==0){
30             if (b.count(p)) d=-1;else d=1;
31             while (x%p==0) x/=p,cnt+=d;
32         }
33     }
34     if (x!=1){
35         if (b.count(x)) d=-1;else d=1;
36         cnt+=d;
37     }
38     return (mp[rec]=cnt);
39 }
40 int main(){
41     n=read();m=read();
42     for (int i=1;i<=n;i++) a[i]=read();
43     for (int i=1;i<=m;i++) {int x=read();b.insert(x);}
44     int ans=0;
45     g[1]=a[1];
46     for (int i=2;i<=n;i++) g[i]=gcd(g[i-1],a[i]);
47     for (int i=1;i<=n;i++)
48      ans+=F(a[i]);
49     f[0]=ans;
50     for (int i=1;i<=n;i++){
51         int s=F(g[i]);
52         f[i]=-0x3f3f3f3f;
53         for (int j=i-1;j>=0;j--)
54          f[i]=std::max(f[i],f[j]-s*(i-j));
55     }
56     ans=-0x3f3f3f3f;
57     for (int i=0;i<=n;i++) ans=std::max(ans,f[i]);
58     printf("%d\n",ans);
59 }

还有一种贪心做法,就是从后往前取,能取就取,直到变小为止。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<map>
 7 #include<set>
 8 std::map<int,int>mp;
 9 std::set<int>b;
10 int n,m,f[200005],g[200005],a[200005];
11 int read(){
12     char ch=getchar();int t=0,f=1;
13     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
14     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
15     return t*f;
16 }
17 int gcd(int a,int b){
18     if (b==0) return a;
19     else return gcd(b,a%b);
20 }
21 int F(int x){
22     if (x<=1) return 0;
23     if (b.count(x)) return -1;
24     int rec=x,res=0;
25     if (mp.find(rec)!=mp.end()) return mp[rec];
26     int d=0,cnt=0;
27     for (int i=2;i*i<=rec;i++){
28         int p=i;
29         if (x%p==0){
30             if (b.count(p)) d=-1;else d=1;
31             while (x%p==0) x/=p,cnt+=d;
32         }
33     }
34     if (x!=1){
35         if (b.count(x)) d=-1;else d=1;
36         cnt+=d;
37     }
38     return (mp[rec]=cnt);
39 }
40 int main(){
41     n=read();m=read();
42     for (int i=1;i<=n;i++) a[i]=read();
43     for (int i=1;i<=m;i++) {int x=read();b.insert(x);}
44     int ans=0;
45     g[1]=a[1];
46     for (int i=2;i<=n;i++) g[i]=gcd(g[i-1],a[i]);
47     for (int i=1;i<=n;i++)
48      ans+=F(a[i]);
49     for (int i=n;i>=1;i--){
50         int s=F(g[i]);
51         if (s<0){
52             ans-=s*i;
53             int t=g[i];
54             for (int j=1;j<=i;j++)
55              g[j]/=t;
56         }
57     }
58     printf("%d\n",ans);
59 }

转载于:https://www.cnblogs.com/qzqzgfy/p/5608412.html

Codeforces 494D Upgrading Array相关推荐

  1. Codeforces 1054D Changing Array

    Codeforces 1054D Changing Array 做法:给定一个序列,每个数可以把在2进制k位下取反,也可以不变,在改变后,这个序列异或和不为0的区间的个数.考虑如何求出尽可能少的异或为 ...

  2. CodeForces - 1610B Kalindrome Array

    B. Kalindrome Array time limit per test1 second memory limit per test256 megabytes An array [b1,b2,- ...

  3. codeforces EDU suffix array

    本文以codeforces EDU suffix array为资料 content introdcution suffix array height array lcp problems & ...

  4. [codeforces 1343B] Balanced Array 奇+奇=偶,奇+偶=奇,偶+偶=偶

    Codeforces Round #636 (Div. 3)   比赛人数12253 [codeforces 1343B]   Balanced Array   奇+奇=偶,奇+偶=奇,偶+偶=偶 总 ...

  5. CodeForces - 1539F Strange Array(线段树区间合并)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,规定位置 iii 的贡献是:设 x=a[i]x=a[i]x=a[i],选择一个包含 iii 的区间 [l,r][l,r][l,r],将其中 ...

  6. CodeForces - 1534E Lost Array(bfs+交互)

    题目链接:点击查看 题目大意:初始时给出一个长度为 nnn 的序列,每次可以询问 kkk 个位置的异或和,现在需要以最少的询问获得整个序列的异或和 题目分析:因为是异或,我们只关心每个位置被询问的次数 ...

  7. codeforces 1367B - Even Array

    B. Even Array time limit per test2 seconds memory limit per test256 megabytes inputstandard input ou ...

  8. 【Codeforces】808D Array Division(前后两部分和相等)

    http://codeforces.com/contest/808/problem/D 给你一个数组,问:是否可以通过移动一个数字的位置,求只能移动一次,使得这个数组前后部分的和相等,前后部分不一定等 ...

  9. CodeForces - 817D Imbalanced Array(单调栈)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,求出所有子区间的最大值与最小值之差的和 题目分析:不难看出最大值和最小值之差的和可以拆开,拆成最大值之和与最小值之和之差,现在问题转换为如 ...

最新文章

  1. 3、深入理解计算机系统笔记:程序的机器级表示
  2. ttc转ttf在线网站_文件格式怎么在线互转?迅捷PDF转换器告诉你
  3. 一个简单的GridView分页
  4. 基本的Socket通信
  5. 信奥中的数学:二次互反律
  6. Theano中的Function
  7. cad显示驱动程序文件已丢失或损坏_win7系统下打开AutoCAD 2014时显示驱动程序文件.hdi丢失如何解决...
  8. 如果降低sbus总线的传输速率/帧率,sbus怎样转UART,sbus接到4G
  9. Python中的stringIO模块
  10. pythonmt4通讯swot矩阵_swot分析矩阵范例
  11. SQLServer数据库日志处理
  12. ATmega128单片机](熔丝修改后无法烧录程序情况)
  13. python父亲节快乐_打算送亲戚家孩子新年礼物,有哪些礼物孩子喜欢且有意义?...
  14. 趣拿整合线上线下营销,解决新品推广痛点
  15. 用python实现erp出入库_ERP采购入库成品入库流程(精)
  16. 3DCNN参数解析:2013-PAMI-3DCNN for Human Action Recognition
  17. 用verilog HDL实现数字基带信号的2FSK调制
  18. pda输出模式设置,在pda手持设备上,文本框的输入监听焦点受输出模式影响
  19. 收藏微软面试智力题 (附答案)
  20. 武汉星淘惠:武汉跨境产业稳步发展,线上选品大会已圆满落幕

热门文章

  1. logback配置控制打印台异常信息_logback异常输出详细信息(调用堆栈)分析
  2. mysql的聚合函数综合案例_MySQL常用聚合函数详解
  3. C++_泛型编程与标准库(八)
  4. 联想一体计算机排行,2019最具性价比一体机推荐 电脑一体机十大最新排名
  5. mysql二级索引_mysql——二级索引(辅助索引)
  6. 【java 性能优化实战】3 工具实践:如何获取代码性能数据?
  7. 渗透测试与自动化安全测试工具比较
  8. python:自动化测试 playwright 库上传和下载
  9. Python的零基础超详细讲解(第三天)-Python的基础语法
  10. Python开发基础总结之模块+日志+自省