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

求 sum(f[a[i]]) 的最大值。

析:因为f(1) = 0,否则如果是好素数,那么就加一,如果是坏素数就减一,很明显每个数 f(a[i]) 的值就是好素数的数目,送去坏素数的数目,

然后求总的和,这样可以预处理出所有的 gcd,好素数的个数,坏素数的个数,然后dp[i] 表示 sum(f(a[i])) 前 i 个的和最大值。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e16;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 5000 + 10;
const int mod = 1000000007;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
vector<int> prime;
bool vis[(int)1e5+5];
int a[maxn];
void init(){
int t = (int)sqrt(1e9 + 0.5);
for(int i = 2; i <= t; ++i) if(!vis[i]){
prime.push_back(i);
for(int j = i*i; j <= t; j += i) vis[j] = true;
}
} int dp[maxn];
int good[maxn];
int bad[maxn];
int gg[maxn];
int gb[maxn];
int g[maxn];
map<int, bool> mp; void solve(int i, int t, int *good, int *bad){
for(int j = 0; j < prime.size() && t > 1; ++j) if(t % prime[j] == 0){
if(mp[prime[j]]){
while(t % prime[j] == 0){
t /= prime[j];
++bad[i];
}
}
else while(t % prime[j] == 0){
t /= prime[j];
++good[i];
}
}
if(t > 1 && mp[t]) ++bad[i];
else if(t > 1) ++good[i];
} int main(){
init();
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; ++i){
scanf("%d", a+i);
g[i] = gcd(g[i-1], a[i]);
}
for(int i = 0; i < m; ++i){
int x;
scanf("%d", &x);
mp[x] = true;
} for(int i = 1; i <= n; ++i){
solve(i, a[i], good, bad);
good[i] += good[i-1];
bad[i] += bad[i-1];
solve(i, g[i], gg, gb);
} for(int i = 0; i <= n; ++i) dp[i] = -INF;
dp[0] = 0;
for(int i = 1; i <= n; ++i)
for(int j = 0; j < i; ++j)
dp[i] = max(dp[i], dp[j]+good[i]-good[j]+bad[j]-bad[i]+max(0, (i-j)*(gb[i]-gg[i]))); printf("%d\n", dp[n]);
return 0;
}

  

CodeForces 402D Upgrading Array (数学+DP)的更多相关文章

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

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

  2. Codeforces 494D Upgrading Array

    http://codeforces.com/contest/494/problem/D 题意:给一个数组,和一个坏质数集合,可以无数次地让1到i这些所有数字除以他们的gcd,然后要求Σf(a[i])的 ...

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

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

  4. 数学+DP Codeforces Round #304 (Div. 2) D. Soldier and Number Game

    题目传送门 /* 题意:这题就是求b+1到a的因子个数和. 数学+DP:a[i]保存i的最小因子,dp[i] = dp[i/a[i]] +1;再来一个前缀和 */ /***************** ...

  5. 数学+dp HDOJ 5317 RGCDQ

    题目传送门 /* 题意:给一个区间,问任意两个数的素数因子的GCD最大 数学+dp:预处理出f[i],发现f[i] <= 7,那么用dp[i][j] 记录前i个f[]个数为j的数有几个, dp[ ...

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

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

  7. Codeforces 1077C Good Array 坑 C

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

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

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

  9. codeforces 407C Curious Array

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

随机推荐

  1. hadoop-sqoop学习笔记

    ======导入==== sqoop import --connect jdbc:mysql://20.12.20.165:3306/luo0907 --username root --passwor ...

  2. Thinkphp 自定义404页面

    一. 手册->调试->异常处理 在公共config.php 中加入: 'TMPL_EXCEPTION_FILE' => '/Public/404.html', //访问不存在的跳转 ...

  3. 隐藏select中的“请选择”项

    <select> <option value="" style="display: none">请选择</option> & ...

  4. RabbitMQ在windows环境下的安装

    最近一直想入手一台电脑,作为linux服务器,由于经济状况也没有入手,现在就先介绍windows环境下安装rabbitMQ. RabbitMQ是什么 ? RabbitMQ是一个在AMQP基础上完整的, ...

  5. 如何测试远端TCP和UDP端口是否开放

    项目遇到问题时首先排查网络是否正常是一个重要的方面.遇到很多次,同事找我解决问题,最后发现却是IP或端口不通的问题.然而就是这么个简单的问题,对方却花费了甚至一天的时间排查原因. 现在大部分项目都是用 ...

  6. 洛谷【P2024】[NOI2001]食物链

    浅谈并查集:https://www.cnblogs.com/AKMer/p/10360090.html 题目传送门:https://www.luogu.org/problemnew/show/P202 ...

  7. springboot启动异常:java.lang.IllegalArgumentException: Could not resolve placeholder 'xxx.xxx.xxx' in value "${xxx.xxx.xxx}"

    场景: 本地启动正常,部署到服务器上启动时启动tomcat失败,显示上面的问题. 原因: 本地打包的时候没有修改指定的配置文件名称(本地只有一份配置文件). 在打包到服务器上时指定的配置文件命名会去查 ...

  8. IP Fragmentation(IP分片)

    https://www.cisco.com/c/en/us/tech/ip/index.html IP协议在传输数据包时,将数据报文分为若干分片进行传输,并在目标系统中进行重组,这一过程称为分片(Fr ...

  9. htmlunit 自动化提交/获取网页数据,自动化测试

    开源组件: https://sourceforge.net/projects/htmlunit/ demo public void post() { try { WebClient client = ...

  10. Windows Server 2008 R2换SID要注意

    今天刚装Windows2008R2,准备做实验.同样,我对虚拟机采用了母盘和差异磁盘.在新建好的虚拟机上使用NewSID执行更新SID操作时,一切正常,但当更新完并重启进入系统后,竟然蓝屏了.   原 ...