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以后的部分。

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

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
std::map<int,int>mp;
std::set<int>b;
int n,m,f[],g[],a[];
int read(){
char ch=getchar();int t=,f=;
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
int gcd(int a,int b){
if (b==) return a;
else return gcd(b,a%b);
}
int F(int x){
if (x<=) return ;
if (b.count(x)) return -;
int rec=x,res=;
if (mp.find(rec)!=mp.end()) return mp[rec];
int d=,cnt=;
for (int i=;i*i<=rec;i++){
int p=i;
if (x%p==){
if (b.count(p)) d=-;else d=;
while (x%p==) x/=p,cnt+=d;
}
}
if (x!=){
if (b.count(x)) d=-;else d=;
cnt+=d;
}
return (mp[rec]=cnt);
}
int main(){
n=read();m=read();
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=m;i++) {int x=read();b.insert(x);}
int ans=;
g[]=a[];
for (int i=;i<=n;i++) g[i]=gcd(g[i-],a[i]);
for (int i=;i<=n;i++)
ans+=F(a[i]);
f[]=ans;
for (int i=;i<=n;i++){
int s=F(g[i]);
f[i]=-0x3f3f3f3f;
for (int j=i-;j>=;j--)
f[i]=std::max(f[i],f[j]-s*(i-j));
}
ans=-0x3f3f3f3f;
for (int i=;i<=n;i++) ans=std::max(ans,f[i]);
printf("%d\n",ans);
}

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

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
std::map<int,int>mp;
std::set<int>b;
int n,m,f[],g[],a[];
int read(){
char ch=getchar();int t=,f=;
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
int gcd(int a,int b){
if (b==) return a;
else return gcd(b,a%b);
}
int F(int x){
if (x<=) return ;
if (b.count(x)) return -;
int rec=x,res=;
if (mp.find(rec)!=mp.end()) return mp[rec];
int d=,cnt=;
for (int i=;i*i<=rec;i++){
int p=i;
if (x%p==){
if (b.count(p)) d=-;else d=;
while (x%p==) x/=p,cnt+=d;
}
}
if (x!=){
if (b.count(x)) d=-;else d=;
cnt+=d;
}
return (mp[rec]=cnt);
}
int main(){
n=read();m=read();
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=m;i++) {int x=read();b.insert(x);}
int ans=;
g[]=a[];
for (int i=;i<=n;i++) g[i]=gcd(g[i-],a[i]);
for (int i=;i<=n;i++)
ans+=F(a[i]);
for (int i=n;i>=;i--){
int s=F(g[i]);
if (s<){
ans-=s*i;
int t=g[i];
for (int j=;j<=i;j++)
g[j]/=t;
}
}
printf("%d\n",ans);
}

Codeforces 494D Upgrading Array的更多相关文章

  1. Codeforces 402D Upgrading Array:贪心 + 数学

    题目链接:http://codeforces.com/problemset/problem/402/D 题意: 给你一个长度为n的数列a[i],又给出了m个“坏质数”b[i]. 定义函数f(s),其中 ...

  2. CodeForces 402D Upgrading Array (数学+DP)

    题意:给出一个数列,可以进行一种操作将某一个前缀除去他们的gcd,有一个函数f(x),f(1) = 0 , f(x) = f(x/p)+1,f(x) = f(x/p)-1(p是坏素数), 求 sum( ...

  3. Codeforces 482B Interesting Array(线段树)

    题目链接:Codeforces 482B Interesting Array 题目大意:给定一个长度为N的数组,如今有M个限制,每一个限制有l,r,q,表示从a[l]~a[r]取且后的数一定为q,问是 ...

  4. Codeforces 1077C Good Array 坑 C

    Codeforces 1077C Good Array https://vjudge.net/problem/CodeForces-1077C 题目: Let's call an array good ...

  5. codeforces 482B. Interesting Array【线段树区间更新】

    题目:codeforces 482B. Interesting Array 题意:给你一个值n和m中操作,每种操作就是三个数 l ,r,val. 就是区间l---r上的与的值为val,最后问你原来的数 ...

  6. codeforces 407C Curious Array

    codeforces 407C Curious Array UPD: 我觉得这个做法比较好理解啊 参考题解:https://www.cnblogs.com/ChopsticksAN/p/4908377 ...

  7. codeforces 797 E. Array Queries【dp,暴力】

    题目链接:codeforces 797 E. Array Queries   题意:给你一个长度为n的数组a,和q个询问,每次询问为(p,k),相应的把p转换为p+a[p]+k,直到p > n为 ...

  8. codeforces 402 D. Upgrading Array(数论+贪心)

    题目链接:http://codeforces.com/contest/402/problem/D 题意:给出一个a串和素数串b .f(1) = 0; p为s的最小素因子如果p不属于b , 否则 . a ...

  9. codeforces Upgrading Array

    思路:对于每个数分解质因子然后记录每一个质因子的个数,对与在b中出现的质因子就减去1,否则加1,求出总的,然后从后面一次对它们的最大公约数,然后判断除以最大公约数之后,改变量是不是变化,求最大值,变化 ...

随机推荐

  1. iptables 顺序

    -A INPUT -s 115.236.6.6/32 -p udp -m udp --dport 111 -j ACCEPT -A INPUT -s 10.175.197.98/32 -p udp - ...

  2. BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁

    2023: [Usaco2005 Nov]Ant Counting 数蚂蚁 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 56  Solved: 16[S ...

  3. hdu4405:概率dp

    题意: 总共有n+1个格子:0-n 初始情况下在 0号格子 每次通过掷骰子确定前进的格子数 此外 还有一些传送门可以瞬间从 u 点传送到 v 点(必须被传送) 求走到(或超过)n点总共需要掷多少次骰子 ...

  4. spring加载properties配置文件

    public static void main(String[] args){    String path="E:/workspace/bocMarketData/src/config/P ...

  5. syslog_test.c 简单的syslog函数

    #cat syslog_test.c #include<stdio.h> #include<stdlib.h> #include<syslog.h> int mai ...

  6. vue-cli 脚手架总结

    > vue-cli 的脚手架项目模板有browserify 和 webpack , 现在自己在用的是webpack , 官网给出了两个模板: webpack-simple 和 webpack 两 ...

  7. Windows Server 2008搭建域控制器《转载51CTO.com》

    Windows Server 2008搭建域控制器 引入 在小型网络中,管理员通常独立管理每一台计算机,如最为常用的用户管理.但当网络规模扩大到一定程度后,如超过 10 台计算机,而每台计算机上有 1 ...

  8. asp.net实现将网页内容输出到word并下载到本地

    个人觉得要实现这个功能如果没有类库提供的几个关键函数,还是比较繁琐的.所以首先介绍几个将要在代码中使用的关键函数和参数,然后再说函数实现.注意问题等. 关键函数: 1.函数原型:Response.Ap ...

  9. oracle插入例子

    string sql = "insert into EMST_JC_SBXX(XL,SBBM,SBWH,SBMC,CCBM,XNCS,CZXL,ZL,GL,ZZCJ,TCRQ,SYQX,XH ...

  10. SQL cmd 实用工具学习 -1

    启动 sqlcmd 实用工具并连接到 SQL Server 的默认实例 在"开始"菜单上,单击"运行". 在"打开"框中,键入 cmd,然后 ...