Codeforces 494D Upgrading Array
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的更多相关文章
- Codeforces 402D Upgrading Array:贪心 + 数学
题目链接:http://codeforces.com/problemset/problem/402/D 题意: 给你一个长度为n的数列a[i],又给出了m个“坏质数”b[i]. 定义函数f(s),其中 ...
- 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( ...
- Codeforces 482B Interesting Array(线段树)
题目链接:Codeforces 482B Interesting Array 题目大意:给定一个长度为N的数组,如今有M个限制,每一个限制有l,r,q,表示从a[l]~a[r]取且后的数一定为q,问是 ...
- Codeforces 1077C Good Array 坑 C
Codeforces 1077C Good Array https://vjudge.net/problem/CodeForces-1077C 题目: Let's call an array good ...
- codeforces 482B. Interesting Array【线段树区间更新】
题目:codeforces 482B. Interesting Array 题意:给你一个值n和m中操作,每种操作就是三个数 l ,r,val. 就是区间l---r上的与的值为val,最后问你原来的数 ...
- codeforces 407C Curious Array
codeforces 407C Curious Array UPD: 我觉得这个做法比较好理解啊 参考题解:https://www.cnblogs.com/ChopsticksAN/p/4908377 ...
- codeforces 797 E. Array Queries【dp,暴力】
题目链接:codeforces 797 E. Array Queries 题意:给你一个长度为n的数组a,和q个询问,每次询问为(p,k),相应的把p转换为p+a[p]+k,直到p > n为 ...
- codeforces 402 D. Upgrading Array(数论+贪心)
题目链接:http://codeforces.com/contest/402/problem/D 题意:给出一个a串和素数串b .f(1) = 0; p为s的最小素因子如果p不属于b , 否则 . a ...
- codeforces Upgrading Array
思路:对于每个数分解质因子然后记录每一个质因子的个数,对与在b中出现的质因子就减去1,否则加1,求出总的,然后从后面一次对它们的最大公约数,然后判断除以最大公约数之后,改变量是不是变化,求最大值,变化 ...
随机推荐
- list排序成员函数对string对象与char*对象排序的差别
对list容器中的对象排序,不能使用sort()算法,只能采用其自身的排序函数sort().因为,算法sort()只支持随机存取的容器的排序,如vector等. 对基本数据对象list排序:成员函数s ...
- java多个listener监听
java 多个listener 监听方法 在class 名称上一行添加@Listeners 括号中用逗号隔开 @Listeners({com.example.MyListener.class,com. ...
- JQuery的父、子、兄弟节点查找,节点的子节点循环
Query.parent(expr) //找父元素 jQuery.parents(expr) //找到所有祖先元素,不限于父元素 jQuery.children( ...
- 不可视对象的自己主动实例化BUG
PB有个隐藏BUG会占用内存.影响效率. 先来做个样例吧 (1)创建一个不可视对象n_base,勾选Autolnstantiate属性 初始化事件constructor里面写messagebox('c ...
- 让你不再纠结GitHub:Git起步
一.关于版本控制 版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修订情况的系统.我们通常仅对保存着软件源代码的文本文件做版本控制,但实际上,你可以对任何类型的文件进行版本控制. 采用版本控制 ...
- Java第三周学习日记
Day01 1.线程 进程:进程就是正在运行的应用程序.进程负责了内存空间的划分. 线程:一个进程中的代码是由线程去执行的,线程也就是其中一个执行路径. 多线程:一个进程中有多个线程可以同时执行任务. ...
- JavaScript学习笔记之 数组方法一 堆栈 和队列
数组的方法 以及 堆栈的操作的方法 JavaScript是一种弱类型语言,不像其它程序语言需要严格定义数据类型.在JavaScript中数组可以任意修改变动,这样也就出现了一个问题,如果边遍历数组边操 ...
- nagios和zabbix自定义监控脚本
一. 自定义nagios监控脚本1. 在客户端上创建脚本/usr/local/nagios/libexec/check_disk.shvim /usr/local/nagios/libexec/ch ...
- My way on Linux - [Shell基础] - Bash Shell中判断文件、目录是否存在或者判断其是否具有某类属性(权限)的常用方法
Conditional Logic on Files # 判断文件是否存在及文件类型 -a file exists. #文件存在 -b file exists and is a block speci ...
- OpenGL ES 2.0 限定符
限定符 说明 作用 attribute 一般用于各个顶点各不相同的量,如顶点位置.颜色等 属性限定符,修饰的变量用来接收渲染管线传递进顶点着色器的当前顶点的各种属性值. 只能用来修饰符点数标量,浮点数 ...