noip2011题解day2

【依旧转自“浅析”】
计算系数

【问题描述】
给定一个多项式(ax + by)^k,请求出多项式展开后(x^n)*(y^m)项的系数。
【输入】
输入文件名为 factor.in。
共一行,包含 5 个整数,分别为a,b,k,n,m,每两个整数之间用一个空格隔开。
【输出】
输出文件名为 factor.out。
输出共 1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007 取模后的结果。
【输入输出样例】

factor.infactor.out
1 1 3 1 23

【数据范围】

对于 30%的数据,有0≤k≤10;
对于 50%的数据,有a = 1,b = 1;
对于 100%的数据,有0≤k≤1,000,0≤n, m≤k,且n + m = k,0≤a,b≤1,000,000。

【一句话题意】
我还是喜欢只有一句话的题目。
【考察知识点】
数论/二项式系数/组合
【思路】
这题对高三党很有利,学过组合啊。
其实就算不是高三,学OI的也应该知道二项式系数/组合数/杨辉三角,再不行手推几个也就能知道ans=C(k,n)*(a^n)*(b^m)
这里由于是取模,同余只能用于加和乘。但又要算组合数,而组合数公式里有除法,我因此纠结了很久很久,甚至最后都有写高精加减乘除模的想法。
瞬间灵光一闪,C(k,n)=C(k-1,n)+C(k-1,n-1),行了!注意要边加边mod,否则跟没想到一样。

{cc小小吐槽一下:用快速幂就OK了,不用高精。。。。。}
【时间复杂度】
O(k^2)

聪明的质监员

【问题描述】
小 T 是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有n 个矿石,从1到n 逐一编号,每个矿石都有自己的重量wi 以及价值vi。检验矿产的流程是:
1、给定m 个区间[Li,Ri];
2、选出一个参数W;
3、对于一个区间[Li,Ri],计算矿石在这个区间上的检验值Yi :Yi=sum*sumv。sum为[Li,Ri]之间Wi>=W的矿石数量,sumv为其价值和。
这批矿产的检验结果Y 为各个区间的检验值之和。 
若这批矿产的检验结果与所给标准值S 相差太多,就需要再去检验另一批矿产。小T不想费时间去检验另一批矿产,所以他想通过调整参数W 的值,让检验结果尽可能的靠近标准值S,即使得S-Y 的绝对值最小。请你帮忙求出这个最小值。
【输入】
输入文件 qc.in。
第一行包含三个整数 n,m,S,分别表示矿石的个数、区间的个数和标准值。
接下来的 n 行,每行2 个整数,中间用空格隔开,第i+1 行表示i 号矿石的重量wi 和价值vi 。
接下来的 m 行,表示区间,每行2 个整数,中间用空格隔开,第i+n+1 行表示区间[Li,Ri]的两个端点Li 和Ri。注意:不同区间可能重合或相互重叠。
【输出】
输出文件名为 qc.out。
输出只有一行,包含一个整数,表示所求的最小值。
【输入输出样例】

qc.inqc.out
5 3 15
1 5
2 5
3 5
4 5
5 5
1 5
2 4 
3 3
10

【输入输出样例说明】
当 W 选4 的时候,三个区间上检验值分别为20、5、0,这批矿产的检验结果为25,此时与标准值S 相差最小为10。
【数据范围】
对于 10%的数据,有1≤n,m≤10;
对于 30%的数据,有1≤n,m≤500;
对于 50%的数据,有1≤n,m≤5,000;
对于 70%的数据,有1≤n,m≤10,000;
对于 100%的数据,有1≤n,m≤200,000,0 < wi, vi≤10^6,0 < S≤10^12,1≤Li≤Ri≤n。

【一句话题意】
找到一个参数W,使得所有区间检验值之和与S最接近。
【考察知识点】
二分答案/部分和优化
【思路】
我就说一定会考二分答案的嘛。。。
根据检验值之和的定义,很容易发现其值随W递增而递减。那么我们就只要在[0,maxw]中二分出一个参数W,不断逼近S即可。
二分不复杂,但是算检验值之和的时候,注意题中N数据范围,必须要用O(n)的算法得出检验值之和。
和昨天一样,预设两个数组sum[i]和sumv[i]。sum[i]表示前i个矿石中,w[i]>=W的矿石数量之和;sumv[i]表示前i个矿石中,w[i]>=W的矿石价值之和。
那么对于每个区间[l,r],检验值就是(sum[r]-sum[l-1])*(sumv[r]-sumv[l-1]),累加即可。

目测检验值之和不会爆int64,否则又悲剧了。。。。
根据"sevenkplus"的说法,m个区间200000*n个矿石200000*最大总价值(最大价值10^6*最大区间长度2*10^5)>2^64,极限数据的确会爆int64。因此在计算检验值之和的时候,如果某时刻答案>=S*3(因为要算的是差值,S*2+1可以,但是保险起见还是用S*3),直接退出。

到此时还剩2个小时左右,然后我观察第三题的难度,果断先放弃,去对拍前2题了。事实证明这个策略还是挺对的,至少因为如果我不对拍,第一题爆0。
【时间复杂度】
O((n+m)*log maxw)

观光公交

【问题描述】
风景迷人的小城 Y 市,拥有n 个美丽的景点。由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务。观光公交车在第0 分钟出现在1号景点,随后依次前往2、3、4……n 号景点。从第i 号景点开到第i+1 号景点需要Di 分钟。任意时刻,公交车只能往前开,或在景点处等待。
设共有 m 个游客,每位游客需要乘车1 次从一个景点到达另一个景点,第i 位游客在Ti 分钟来到景点Ai,希望乘车前往景点Bi(Ai<Bi)。为了使所有乘客都能顺利到达目的地,公交车在每站都必须等待需要从该景点出发的所有乘客都上车后才能出发开往下一景点。假设乘客上下车不需要时间。
一个乘客的旅行时间,等于他到达目的地的时刻减去他来到出发地的时刻。因为只有一辆观光车,有时候还要停下来等其他乘客,乘客们纷纷抱怨旅行时间太长了。于是聪明的司机ZZ 给公交车安装了k 个氮气加速器,每使用一个加速器,可以使其中一个Di 减1。对于同一个Di 可以重复使用加速器,但是必须保证使用后Di 大于等于0。
那么 ZZ 该如何安排使用加速器,才能使所有乘客的旅行时间总和最小?
【输入】
输入文件名为 bus.in。
第 1 行是3 个整数n, m, k,每两个整数之间用一个空格隔开。分别表示景点数、乘客数和氮气加速器个数。
第 2 行是n-1 个整数,每两个整数之间用一个空格隔开,第i 个数表示从第i 个景点开往第i+1 个景点所需要的时间,即Di。
第 3 行至m+2 行每行3 个整数Ti, Ai, Bi,每两个整数之间用一个空格隔开。第i+2 行表示第i 位乘客来到出发景点的时刻,出发的景点编号和到达的景点编号。
【输出】
输出文件名为 bus.out。共一行,包含一个整数,表示最小的总旅行时间。
【输入输出样例】

bus.inbus.out
3 3 2
1 4
0 1 3
1 1 2
5 2 3
10

【输入输出样例说明】
对 D2 使用2 个加速器,从2 号景点到3 号景点时间变为2 分钟。
公交车在第 1 分钟从1 号景点出发,第2 分钟到达2 号景点,第5 分钟从2 号景点出发,第7 分钟到达3 号景点。
第 1 个旅客旅行时间 7-0 = 7 分钟。
第 2 个旅客旅行时间 2-1 = 1 分钟。
第 3 个旅客旅行时间 7-5 = 2 分钟。
总时间 7+1+2 = 10 分钟。
【数据范围】
对于 10%的数据,k=0;
对于 20%的数据,k=1;
对于 40%的数据,2 ≤ n ≤ 50,1 ≤ m≤ 1,000,0 ≤ k ≤ 20,0 ≤ Di ≤ 10,0 ≤ Ti ≤ 500;
对于 60%的数据,1 ≤ n ≤ 100,1 ≤ m≤ 1,000,0 ≤ k ≤ 100,0 ≤ Di ≤ 100,0 ≤ Ti ≤ 10,000;
对于 100%的数据,1 ≤ n ≤ 1,000,1 ≤ m ≤ 10,000,0 ≤ k ≤ 100,000,0 ≤ Di ≤ 100,0 ≤ Ti ≤ 100,000。

【一句话题意】
给你k个氮气加速器,求乘客的旅行时间最小值。
【考察知识点】
贪心?
【思路】
恩,果断没有思路。
最后还剩1个小时少一点,迅速写了个无任何剪枝DFS搜索,且貌似连计算时间和都搞错了。
杯具!!!!
不过样例过了- -……

maxArrive i 表示从i点出发的人,Ti的最大值,即最迟到达时间,无人出发则为0。enter i表示i点的最早到达时间,那么
enter i=max{enter i-1,maxArrive i-1}+Di-1
那么消耗的总时间就是
sum((enter bi) – Ti)(1<=i<=m)

循环k次。每次枚举i∈[1,m],计算Di=(Di)-1  (Di>=1)后的总时间,从中找一个时间最少的进行下一步即可。(贴吧上的,正确性值得探讨)

【时间复杂度】
O(nk)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值