总目录详见https://blog.csdn.net/mrcrack/article/details/84471041
做题原则,找不到测评地址的题不做。2018-11-28
重走长征路---OI每周刷题记录---3月22日 2014
本周共计26题+1题
测评地址:
高精度:
1.「bzoj1263」整数划分
费用流:
2.「bzoj1221」软件开发
3.「bzoj2424」订货
4.「bzoj3171」循环格
gcd:
5.「bzoj1385」Division expression
6.「poj2115」C Looooops
exgcd:
7.「bzoj1477」青蛙的约会
网络流:
8.「bzoj1412」狼和羊的故事
9.「bzoj1934」善意的投票
模拟:
10.「cf402A」Nuts
暴力:
11.「cf402B」Trees in a Row
辛普森积分:
12.「bzoj2178」圆的面积并
最小树形图:
13.「poj3164」Command Network
线段树:
14.「bzoj3211」花神游历各国
欧拉函数:
15.「bzoj2190」仪仗队
博弈论:
16.「bzoj1982」Moving Pebbles
背包dp:
17.「poj2392」Space Elevator
dfs:
18.木棍
素数筛法:
19.「JoyOI1020」寻找质因数 //在线测评地址http://codevs.cn/problem/2158/
trie:
20.「poj2001」Shortest Prefixes
并查集:
21.「poj2588」Snakes「JoyOI1460」旅行
dfs:
22.「poj2157」Maze
斜率优化:
23.「bzoj1010」玩具装箱 //在线测评地址https://www.luogu.org/problemnew/show/P3195
27.Print Article //在线测评地址https://vjudge.net/problem/HDU-3507
期望:
24.「cogs1489」玩纸牌
hash:
25.「codevs3013」单词背诵
字符串:
26.最小字符串
题解:
高精度:
1.「bzoj1263」整数划分
费用流:
2.「bzoj1221」软件开发
3.「bzoj2424」订货
4.「bzoj3171」循环格
gcd:
5.「bzoj1385」Division expression
6.「poj2115」C Looooops
exgcd:
7.「bzoj1477」青蛙的约会
网络流:
8.「bzoj1412」狼和羊的故事
9.「bzoj1934」善意的投票
模拟:
10.「cf402A」Nuts
暴力:
11.「cf402B」Trees in a Row
辛普森积分:
12.「bzoj2178」圆的面积并
最小树形图:
13.「poj3164」Command Network
线段树:
14.「bzoj3211」花神游历各国
欧拉函数:
15.「bzoj2190」仪仗队
博弈论:
16.「bzoj1982」Moving Pebbles
背包dp:
17.「poj2392」Space Elevator
dfs:
18.木棍
素数筛法:
19.「JoyOI1020」寻找质因数
//2158 寻找质因数
//在线测评地址http://codevs.cn/problem/2158/
//准备实践 线性筛素数 对线性筛过程更清楚。
//准备 在线性筛素数的过程中,弄个离线算法,一次成功。
//样例通过,提交AC。时间是朴素算法的1/3。2019-2-16 12:14
//以下代码是根据线性筛素数编写得出,not_prime[i]用来存储i的最大质因数。
#include <stdio.h>
#include <string.h>
#define maxn 20100
int prime[maxn],not_prime[maxn],tot=0;
void linear_shaker(int x){//筛出1-x之间的素数
int i,j;
memset(not_prime,0,sizeof(not_prime)),not_prime[1]=1;//not_prime[i]=0,素数,not_prime[i]=1,合数
for(i=2;i<=x;i++){
if(!not_prime[i])prime[++tot]=i,not_prime[i]=i;//i没被筛掉,是素数
for(j=1;prime[j]*i<=x;j++){
not_prime[prime[j]*i]=not_prime[i];//not_prime[prime[j]*i]=1将1改成prime[j],存储最大的质数//合数 筛掉 已找到 素数 i倍的数,此处2<=i<=prime[j]
if(i%prime[j]==0)break;
}
}
}
int main(){
int n,a,b=0,i,ans;//b存储最大质因数
linear_shaker(maxn);
scanf("%d",&n);
while(n--){
scanf("%d",&a);
if(b<not_prime[a])b=not_prime[a],ans=a;
}
printf("%d\n",ans);
return 0;
}
//2158 寻找质因数
//在线测评地址http://codevs.cn/problem/2158/
//A_i=20000,找到2-10000之间的素数,朴素算法i*i<=n,sqrt(2)+sqrt(3)+...+sqrt(10000)<100*2500=2.5*10^5不会超时
//采用桶排序的方式,判定素数。
//再对每个数算约数,判断约数中的最大素数。(i=1;i*i<=n;i++),因约数成对出现,遇到约数是质数则判定。
//A_i=20000,sqrt(20000)=142,N=5000,5000*142=7.1*10^5不会超时
//该题,朴素算法即可AC。
//样例通过,提交60分,测试点3,4,9RE,测试点8RE。
//测试界面,提供了一组数据
//1
//1
//1
//还需特判。
//修改下述思路
//A_i=20000,找到2-20000之间的素数,朴素算法i*i<=n,sqrt(2)+sqrt(3)+...+sqrt(20000)<20000*141=2.82*10^6不会超时
//修改,提交AC。2019-2-16 10:18
//以下为朴素算法的AC代码。
#include <stdio.h>
#include <string.h>
int prime[20010];//此处写成 int prime[10010];
int isPrime(int x){//朴素算法,判定是否素数 返回1,素数,返回0,非素数
int i;
if(x==1)return 0;
if(x==2)return 1;
for(i=2;i*i<=x;i++)
if(x%i==0)return 0;
return 1;
}
int max(int a,int b){
return a>b?a:b;
}
int main(){
int i,n,a,b=1,c=-1,t;//b初始化为1,即为特判
memset(prime,0,sizeof(prime));
for(i=2;i<=20000;i++)//此处写成 for(i=2;i<=10000;i++)
if(isPrime(i))prime[i]=1;//i为素数,则prime[i]=1
scanf("%d",&n);
while(n--){
scanf("%d",&a);
for(i=1;i*i<=a;i++){
if(a%i==0){
t=a/i;//另一个约数
if(prime[i]==1&&i>c)c=i,b=a;
if(prime[t]==1&&t>c)c=t,b=a;//若A_i=20000,确会溢出
}
}
}
printf("%d\n",b);
return 0;
}
trie:
20.「poj2001」Shortest Prefixes
并查集:
21.「poj2588」Snakes「JoyOI1460」旅行
dfs:
22.「poj2157」Maze
斜率优化:
23.「bzoj1010」玩具装箱
//P3195 [HNOI2008]玩具装箱TOY
//在线测评地址https://www.luogu.org/problemnew/show/P3195
//有思路,但数学式子推得很乱,
//翻看https://www.cnblogs.com/Paul-Guderian/p/7259491.html推导
//发现,一个换元,想到了,但没付出实践;一个L++,确实没想到。就这两下,式子变得简单多了。
//dp[j]+(sum[j]+j+L)*(sum[j]+j+L)-(dp[k]+(sum[k]+k+L)*(sum[k]+k+L)<=2*(sum[i]+i)*((sum[j]+j+L)-(sum[k]+k+L))
//样例通过,提交AC。2019-3-6
//建议以下两篇文章一起看,对理解 斜率优化, 很有帮助
//https://www.luogu.org/problemnew/solution/P3195?page=3
//作者: hongzy 更新时间: 2018-10-26 22:45
//作者: Brioche 更新时间: 2018-09-18 17:09
#include <stdio.h>
#define LL long long
#define maxn 50100
LL n,L,sum[maxn],q[maxn],dp[maxn],h,t;
LL getUp(LL k,LL j){
return dp[j]+(sum[j]+j+L)*(sum[j]+j+L)-(dp[k]+(sum[k]+k+L)*(sum[k]+k+L));//此处写成return dp[j]+(sum[j]+j+L)*(sum[j]+j+L)-dp[k]+(sum[k]+k+L)*(sum[k]+k+L);
}
LL getDown(LL k,LL j){
return (sum[j]+j+L)-(sum[k]+k+L);
}
int main(){
LL i,u;
scanf("%lld%lld",&n,&L);
L++,sum[0]=0;
for(i=1;i<=n;i++)scanf("%lld",&sum[i]);
for(i=1;i<=n;i++)sum[i]+=sum[i-1];
dp[0]=0,h=t=1,q[t]=0,t++;
for(i=1;i<=n;i++){
while(h+1<t&&getUp(q[h],q[h+1])<=2*(sum[i]+i)*getDown(q[h],q[h+1]))h++;
u=q[h];
dp[i]=dp[u]+(sum[i]-sum[u]+i-u-L)*(sum[i]-sum[u]+i-u-L);
while(h+1<t&&getUp(q[t-2],q[t-1])*getDown(q[t-1],i)>=getUp(q[t-1],i)*getDown(q[t-2],q[t-1])) t--;
q[t]=i,t++;
}
printf("%lld\n",dp[n]);
return 0;
}
27.Print Article
//Print Article HDU - 3507
//在线测评地址https://vjudge.net/problem/HDU-3507
//通过此文,学习斜率优化https://www.cnblogs.com/orzzz/p/7885971.html
//上文中S[i]表示从a[1]到a[i−1]的数字和 需更正为 S[i]表示从a[1]到a[i]的数字和
//上文中S[i+1]均需改成S[i]
//喜欢此文代码https://blog.csdn.net/bill_yang_2016/article/details/54667902
//喜欢此文代码http://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html
//0 ≤ n ≤ 500000, 0 ≤ M ≤ 1000,采用long long比较稳妥
//return 1.0*(dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]))/(2*sum[j]-2*sum[k]);//此处写成1.0*(dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]))/(2*sum[j]-2*sum[k]);少了return
//由于学新算法的不自信,造成了上述问题,一个return 整整查了2小时。
//删除测试代码,提交Wrong Answer.
//想了想,还是计算精度的问题,该题不能用double,要全程用long long
//修改,提交AC.2019-3-4 19:14
//getUp(q[h],q[h+1])<=sum[i]*getDown(q[h],q[h+1])
//getUp(q[t-2],q[t-1])*getDown(q[t-1],i)>=getUp(q[t-1],i)*getDown(q[t-2],q[t-1])
//为什么要取等号,为了使之后的数据呈现,有尝试的机会,所以等号时,都需弹出队列.2019-3-4 20:08
#include <stdio.h>
#define maxn 500100
#define LL long long
LL sum[maxn],q[maxn],h,dp[maxn],t;
LL getUp(LL k,LL j){
return dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]);
}
LL getDown(LL k,LL j){
return 2*(sum[j]-sum[k]);
}
int main(){
LL n,m,i,u;
while(scanf("%lld%lld",&n,&m)!=EOF){
for(i=1;i<=n;i++)scanf("%lld",&sum[i]);
dp[0]=sum[0]=0,h=t=1,q[t]=0,t++;
for(i=1;i<=n;i++)sum[i]+=sum[i-1];
for(i=1;i<=n;i++){
while(h+1<t&&getUp(q[h],q[h+1])<=sum[i]*getDown(q[h],q[h+1])) h++;//此处写成while(h+1<t&&Slope(h,h+1)<sum[i]) h++;//h位置元素不是最优 //至少2个元素
u=q[h];
dp[i]=dp[u]+(sum[i]-sum[u])*(sum[i]-sum[u])+m;
while(h+1<t&&getUp(q[t-2],q[t-1])*getDown(q[t-1],i)>=getUp(q[t-1],i)*getDown(q[t-2],q[t-1]))t--;//维护下凸包
q[t]=i,t++;
}
printf("%lld\n",dp[n]);
}
return 0;
}
期望:
24.「cogs1489」玩纸牌
hash:
25.「codevs3013」单词背诵
字符串:
26.最小字符串