cf#AIM Tech D. Array GCD (数学+枚举)
来源:互联网 发布:路旁的叶修写真集淘宝 编辑:程序博客网 时间:2024/06/06 15:03
http://codeforces.com/contest/624/problem/D
题意:
给n个数,通过两种操作
操作1:删除一段连续区间,代价 区间长度*b ,只能 选一个区间
操作2:让一个数增加或减少1,一个数只能change 1次。每个数的change花费为a
【不能删除所有的数】 问你最小花费是多少使得 最后所有数的最大公约数大于1.
【不能删除所有的数】.是这个题的切入点,因为不能删除所有数,并且删除区间又是连续的,我们可以知道最后一定会留下a[1]或者a[n],因此我们只需要暴力枚举最后答案为第一个数和最后一个数,及他们加减一共6个数的质因子即可
对于某个因子k,
我们最终的花费 ans= pre[i-1]+(j-i+1)*b +back[j+1];
pre[] 表示1到i-1里面用change使所有数合法的代价,back是使j+1到n的数都合法的change代价
中间的自然就是删除区间的代价
上式变化一下 变成ans=(pre[i-1] + (1-i)*a + a*j+back[j+1] );
显然是关于i,j的两部分 ,我们称i的部分为ff[i]
我们只需要预处理好 关于i 的部分的前缀最小值,然后枚举j的部分就好了
即: 对 固定的一个j,要找到一个i使得ans最小的话,需要从ff[1]到ff[j-1]中选一个最小的ff[i],就能得到一个最小的ans.
因此:
<span style="font-size:18px;">temp1[0]=1e16;for (i=1;i<=n+1;i++)//预处理temp[i]表示,对于固定的j,从1到i选一个i使得ans最小的itemp1[i]=min(temp1[i-1],pre[i-1]+(1-i)*a); </span>然后枚举j 就能得到min——ans了
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;#define ptf(ar1,ar2) pr__ll64f("%I64d:%I64d\n",ar1,ar2);typedef __int64 ll;const ll maxn = 131707+500;int tm[1000005]; ll pre[1000005];ll back[1000005];ll temp1[1000005];ll min(ll a,ll b){return a<b?a:b;} ll ok=0; int prim[10005]; void ff(int x){int ret; for (int i=2; i*i<=x; i++) { if (x%i==0) { prim[++ok]=i; while(x%i==0) x=x/i; } }if (x!=1)prim[++ok]=x;}int main(){ int n,a,b; ll i,j; cin>>n>>a>>b; for (i=1; i<=n; i++) scanf("%d",&tm[i]); for (i=-1;i<=1;i++)//求质因数ff(tm[1]+i),ff(tm[n]+i); sort(prim+1,prim+1+ok); ok=unique(prim+1,prim+1+ok)-prim-1;//去重 ll minn=9223372036854775807; for (ll k=1; k<=ok; k++)//枚举最终以第k个质因数为GCD { for (i=1;i<=n;i++)//求pre[],表示从1到i遇到不合法的数全都change掉的代价{if (tm[i]%prim[k]==0)pre[i]=pre[i-1];elseif ((tm[i]+1)%prim[k]==0||(tm[i]-1)%prim[k]==0)pre[i]=pre[i-1]+b;else{pre[i]=1e16; }//表示从当前i开始后面的不合法的数都不可change要remove}for (i=n;i>=1;i--)//求back[],表示从i到n遇到不合法的数全都change掉的代价{if (tm[i]%prim[k]==0)back[i]=back[i+1];elseif ((tm[i]+1)%prim[k]==0||(tm[i]-1)%prim[k]==0)back[i]=back[i+1]+b;else{back[i]=1e16;break ;}//表示从当前i开始前面的数都不可change要remove} temp1[0]=1e16;for (i=1;i<=n+1;i++)//预处理temp[i]表示,对于固定的j,从1到i选一个i使得ans最小的itemp1[i]=min(temp1[i-1],pre[i-1]+(1-i)*a); for (i=n+1;i>=1&&back[i]!=1e16;i--)//枚举jminn=min(minn,temp1[i]+back[i]+a*(i-1));} printf("%I64d\n",minn); return 0;}
0 0
- cf#AIM Tech D. Array GCD (数学+枚举)
- AIM Tech Round (Div. 2) D. Array GCD(dp)
- AIM Tech Round (Div. 2) D. Array GCD(dp,two pointers)
- AIM Tech Round (Div. 1) B. Array GCD(数论+dp)
- AIM Tech Round 3 (Div. 2) -- B. Checkpoints (枚举)
- AIM Tech Round (Div. 2)(A)数学
- codeforces AIM Tech Round 3 (Div. 2) (A~D)
- CF AIM Tech Round 3 (Div. 2) D - Recover the String
- CF AIM Tech Round 4上紫记
- CF 475D CGCDSSQ 枚举,思维+gcd
- 【DP】AIM Tech Round (Div. 2) D
- CF C. Sorting by Subsequences AIM Tech Round 4 (Div. 2)(简单模拟)
- cf#AIM Tech Round -B. Making a String-贪心/set
- AIM Tech Round 3 (Div. 2) -- D. Recover the String (思路题目--构造字符串)
- AIM Tech Round 3 (Div. 2) -- D. Recover the String (构造字符串)
- AIM Tech Round 3 (Div. 2) D. Recover the String (构造)
- CodeForces AIM Tech Round 3 (Div. 2) D
- Codeforces AIM Tech Round 3 (Div. 2)(A-D 未完)
- JavaScript的this分别代表什么
- 用户爬虫例子
- 爬虫基本知识
- 电脑如何连接万能钥匙解开的WiFi
- mysql_real_escape_string总是返回false
- cf#AIM Tech D. Array GCD (数学+枚举)
- 如何shutdown JBoss AS 7 server
- 使用putty在linux主机和windows主机之间拷贝文件(已测试可执行)
- [hdu4453]looploop [treap/splay]
- jQuery4(Dom与jQuery对象的相互转换)
- uva796 Critical Links(求桥并按边输出)
- Spark RunTime内幕解密
- 蓝桥杯 历届试题 地宫取宝
- WD西部数据移动硬盘官方真伪查询