NOIP2011解题报告-Day2
2012-08-13 21:31
453 查看
计算系数
二项式定理。杨辉三角堆组数+快速幂。Noip的时候还没学二项式定理。。。
聪明的质检员
考场上没看懂题目。。。
发现Y是关于w的减函数,于是二分W,维护前缀和在O(n)的复杂度求出Y。总复杂度O(N log(max{wi}))
PS:w离散化后二分复杂度应该是O(N log(N))时间没有快多少,可能出现在对数上影响不大.
观光公交
首先考虑k=0;如何计算出答案
Leave[i]为最早允许离开i的时间 leave[i]=max{t[j]}(a[j]=i)
可以再读入数据时处理出来leave[a[i]]:=max(T[i],leave[a[i]]);
Get[i]为到达i站时间 Get[i]=max(get[i-1],leave[i-1])+D[i-1];
枚举计算每个旅客的旅行时间
Ans=sigma(i=1..m) (get[b[i]]-T[i])
K=1时枚举给哪个D[i]减一即可
满分做法:贪心
发现给某个D[i]减一后会使后面连续的人等车的车站的乘客提前上车。直到一个车站leave[j]>get[j](车等人),人来的时间是不能跟改变的。所以提前了上车时间的旅客提前了的一分钟要在等人上浪费掉,所以旅行时间不会减小。也就是说令right[i]为i后面第一个满足车等人的站点。
那么在i+1到right[i]这个区间内下车的人的旅行时间都会减小一。维护下车人数的前缀和S。
给D[i]减一所减小的答案为S[right[i]]-S[right[i]]。每次找到最大的加速。找最大可以O(n)暴力,也可以维护堆O(log n)。减的时候有3种情况
1.k很小全部用掉
2.D[i]很小全部减掉(必须保证每个D[i]>=0)
3.i+1..tright[i]中最小的Get[j]-Leave[j](把这个值减成负的会破坏现有的区间的关系,减成负的就变成车等人了)
从这3个值中取最小值用掉
然后O(n)重新计算i..right[i]-1的right值
没写堆,在RQ上过了。Noip的数据很厚道。
二项式定理。杨辉三角堆组数+快速幂。Noip的时候还没学二项式定理。。。
const p=10007;maxk=1000; var a,b,k,n,m:longint; function C(k,m:longint):longint; var f:array[0..maxk,0..maxk] of longint; i,j,n:longint; begin n:=k-m; if(n=0)or(m=0)then exit(1); for i:=0 to n do f[i][0]:=1; for j:=0 to m do f[0][j]:=1; for i:=1 to n do for j:=1 to m do f[i][j]:=(f[i-1][j]+f[i][j-1])mod p; exit(f [m]); end; function exp(a,b:longint):longint; var ans,temp:int64; begin ans:=1;temp:=a; while b<>0 do begin if((b and 1)=1)then ans:=(ans*temp)mod p; temp:=(temp*temp)mod p; b:=b shr 1; end; exit(ans); end; begin readln(a,b,k,n,m); if(n=0)and(m=0) then begin writeln(0); halt; end; a:=a mod p;b:=b mod p; writeln(C(k,m)*int64(exp(a,n))*exp(b,m) mod p); end.
聪明的质检员
考场上没看懂题目。。。
发现Y是关于w的减函数,于是二分W,维护前缀和在O(n)的复杂度求出Y。总复杂度O(N log(max{wi}))
PS:w离散化后二分复杂度应该是O(N log(N))时间没有快多少,可能出现在对数上影响不大.
program qc; uses math; var n,m,i,low,high,mid,tot:longint; s,y:int64; l,r,w,v,sta:array[0..200000] of longint; count,sigmaV:array[0..200000] of int64; f:array[0..1000000] of boolean; function calc(mid:longint):int64; var i:longint; begin calc:=0;count[0]:=0;sigmaV[0]:=0; for i:=1 to n do begin count[i]:=count[i-1]; sigmaV[i]:=sigmaV[i-1]; if w[i]>mid then begin inc(count[i]); inc(sigmaV[i],v[i]); end; end; for i:=1 to m do inc(calc,(count[r[i]]-count[l[i]-1])* (sigmaV[r[i]]-sigmaV[l[i]-1])); end; begin high:=0;low:=maxlongint; readln(n,m,s); for i:=1 to n do begin readln(w[i],v[i]); low:=min(w[i],low); high:=max(w[i],high); f[w[i]]:=true; end; for i:=1 to m do readln(l[i],r[i]); //===lisuanhua=== tot:=1;sta[tot]:=low-1; for i:=low to high do if f[i] then begin inc(tot); sta[tot]:=i; end; inc(tot);sta[tot]:=high+1; //=============== low:=1;high:=tot; while low+1<high do begin mid:=(low+high)>>1; y:=calc(sta[mid]); if y>s then low:=mid else high:=mid; end; writeln(min(abs(s-calc(sta[low])),abs(s-calc(sta[high])))); end. //================================================ program qc; uses math; var n,m,i,low,high,mid:longint; s,y:int64; l,r,w,v:array[0..200000] of longint; count,sigmaV:array[0..200000] of int64; function calc(mid:longint):int64; var i:longint; begin calc:=0;count[0]:=0;sigmaV[0]:=0; for i:=1 to n do begin count[i]:=count[i-1]; sigmaV[i]:=sigmaV[i-1]; if w[i]>mid then begin inc(count[i]); inc(sigmaV[i],v[i]); end; end; for i:=1 to m do inc(calc,(count[r[i]]-count[l[i]-1])* (sigmaV[r[i]]-sigmaV[l[i]-1])); end; begin high:=0;low:=maxlongint; readln(n,m,s); for i:=1 to n do begin readln(w[i],v[i]); low:=min(w[i],low); high:=max(w[i],high); end; for i:=1 to m do readln(l[i],r[i]); dec(low);inc(high); while low+1<high do begin mid:=(low+high)>>1; y:=calc(mid); if y>s then low:=mid else high:=mid; end; writeln(min(abs(s-calc(low)),abs(s-calc(high)))); end.
观光公交
首先考虑k=0;如何计算出答案
Leave[i]为最早允许离开i的时间 leave[i]=max{t[j]}(a[j]=i)
可以再读入数据时处理出来leave[a[i]]:=max(T[i],leave[a[i]]);
Get[i]为到达i站时间 Get[i]=max(get[i-1],leave[i-1])+D[i-1];
枚举计算每个旅客的旅行时间
Ans=sigma(i=1..m) (get[b[i]]-T[i])
K=1时枚举给哪个D[i]减一即可
满分做法:贪心
发现给某个D[i]减一后会使后面连续的人等车的车站的乘客提前上车。直到一个车站leave[j]>get[j](车等人),人来的时间是不能跟改变的。所以提前了上车时间的旅客提前了的一分钟要在等人上浪费掉,所以旅行时间不会减小。也就是说令right[i]为i后面第一个满足车等人的站点。
那么在i+1到right[i]这个区间内下车的人的旅行时间都会减小一。维护下车人数的前缀和S。
给D[i]减一所减小的答案为S[right[i]]-S[right[i]]。每次找到最大的加速。找最大可以O(n)暴力,也可以维护堆O(log n)。减的时候有3种情况
1.k很小全部用掉
2.D[i]很小全部减掉(必须保证每个D[i]>=0)
3.i+1..tright[i]中最小的Get[j]-Leave[j](把这个值减成负的会破坏现有的区间的关系,减成负的就变成车等人了)
从这3个值中取最小值用掉
然后O(n)重新计算i..right[i]-1的right值
没写堆,在RQ上过了。Noip的数据很厚道。
program bus; uses math; CONST maxn=1000; maxm=10000; maxk=1000000; var a,b,t:array[0..maxm] of longint; right,tot,s,cnt,GetIn,GetOff,get,leave,d:array[0..maxn+1] of longint; p,count,n,m,k,i,j,maxcnt,maxi,temp:longint; ans:int64; BEGIN read(n,m,k); for i:=1 to n-1 do read(D[i]); for i:=1 to m do begin read(t[i],a[i],b[i]); inc(GetOff[b[i]]);inc(GetIn[a[i]]); leave[a[i]]:=max(leave[a[i]],t[i]); end; for i:=2 to n do get[i]:=max(leave[i-1],get[i-1])+D[i-1]; p:=1; for i:=1 to n do begin while((p<n)and(leave[p]<get[p]))or(p<=i)do inc(p); right[i]:=p; end; for i:=1 to n do s[i]:=s[i-1]+GetOff[i]; while k>0 do begin maxcnt:=0; for i:=1 to n-1 do if (s[right[i]]-s[i]>maxcnt)and(D[i]>0) then begin maxcnt:=s[right[i]]-s[i]; maxi:=i; end; if maxcnt=0 then break else begin temp:=maxlongint;j:=maxi+1; while(j<n)and(leave[j]<get[j])do begin temp:=min(get[j]-leave[j],temp); inc(j); end; temp:=min(D[maxi],temp);temp:=min(k,temp); dec(k,temp);dec(D[maxi],temp); for j:=maxi+1 to right[i] do get[j]:=max(get[j-1],leave[j-1])+D[j-1]; p:=maxi;count:=GetOff[maxi]; for j:=maxi to right[i]-1 do begin while((p<n)and(leave[p]<get[p]))or(p<=j)do inc(p); if p>=right[j] then break; right[j]:=p; end; end; end; get[1]:=leave[1];get :=max(get ,leave ); for i:=1 to m do inc(ans,get[b[i]]-t[i]); writeln(ans); END.
相关文章推荐
- [2011noip day2]7.27test解题报告
- [2011noip day2]7.27test解题报告
- [解题报告] NOIP 2014 提高组Day2试题
- COGS 631. [NOIP2011] 聪明的质监员 解题报告
- NOIP 2015 Day2 解题报告
- NOIP2015 day2 解题报告
- [NOIP2011] 大整数开方-解题报告
- 洛谷 1314||NOIP 2011 聪明的质检员 二分 解题报告
- 【2011noip普及组】瑞士轮解题报告
- Noip 2011 解题报告 Day1 (铺地毯,选择客栈,Mayan 游戏)
- NOIP 2015 Day2 解题报告(全面)
- NOIP 2011 DAY 1 解题报告(铺地毯,选择客栈,mayan游戏)
- NOIP2011普及组 瑞士轮(重庆一中高2018级信息学竞赛测验4) 解题报告
- NOIP 2015 提高组 day2 解题报告
- codevs 1137||NOIP 2011 计算系数 二项式定理 解题报告
- noip 2015 day2解题报告
- COGS 621.[NOIP2011] 选择客栈 解题报告
- NOIP2011 铺地毯 解题报告(水题)
- NOIP 2016 Day2 解题报告
- 【noip2013】【提高组】【Day2】【解题报告】