重走长征路---OI每周刷题记录---3月22日 2014

总目录详见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.最小字符串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值