Codeforces Good Bye 2015
2016-01-01 12:18
726 查看
第二场CF,3题收场
所以预处理出所有满足条件的数(不超过2000个)
询问是扫一遍即可
dp[i,j]:前i个位置,最后切出来的是后j个dp[i,j]:前i个位置,最后切出来的是后j个
dp[0,j]=1dp[0,j]=1
很明显的O(N3)的DPO(N^3)的DP
dp[i,j]=dp[i−j,k] (k<j)or((x[i−j−k+1,i−j]<x[i−j+1,i])and(k=j))dp[i,j]=dp[i-j,k]~~(k
我们发现每次是在dp[i−j,k]dp[i-j,k]相当于一个前缀和的转移,所以我们维护一个sum[i,j]sum[i,j]
sum[i,j]sum[i,j]负责转移(k<j)(k的部分
当k>jk>j时一定不转移
当k=jk=j时我们要判断两个等长的字符串的大小,我们用预处理来解决这个问题
lcp:最长公共前缀lcp:最长公共前缀
我们定义lcp[i,j]为从i开始和从j开始的最长公共前缀长度lcp[i,j]为从i开始和从j开始的最长公共前缀长度
当两部分相等时lcp大于等于他俩的长度当两部分相等时lcp大于等于他俩的长度
否则我们判断lcp+1位置的字符大小即可否则我们判断lcp+1位置的字符大小即可
最后,lcp可以用O(N2)的DP处理出来lcp可以用O(N^2)的DP处理出来
lcp[i,j]=lcp[i+1,j+1] (x[i]=x[j])lcp[i,j]=lcp[i+1,j+1]~~(x[i]=x[j])
lcp[i,j]=0 (x[i]<>x[j])lcp[i,j]=0~~(x[i]<>x[j])
当然也可以后缀数组求出,,,
T1 New Year and Days
传送门
http://codeforces.com/contest/611/problem/A题目大意
询问2016有多少星期几和几号题解
打表?var n:longint; a:string; begin readln(n,a); if a=' of week' then begin case n of 1:writeln(52); 2:writeln(52); 3:writeln(52); 4:writeln(52); 5:writeln(53); 6:writeln(53); 7:writeln(52); end; end else begin if n<=29 then writeln(12) else if n=30 then writeln(11) else writeln(7); end; end.
T2 New Year and Old Property
传送门
http://codeforces.com/contest/611/problem/B题目大意
询问[L,R]中转为二进制后只有一个0的数的个数题解
L,R<=108L,R<=10^8所以预处理出所有满足条件的数(不超过2000个)
询问是扫一遍即可
var x:array[0..2000]of int64; y:array[0..100]of int64; sum,i,j,k,ans:longint; l,r,t:int64; a,b:int64; begin sum:=0; readln(a,b); y[0]:=1; for i:=1 to 62 do y[i]:=y[i-1]*2; for i:=1 to 61 do for j:=1 to i-1 do begin inc(sum); x[sum]:=y[i]-1-y[j-1]; end; ans:=0; for i:=1 to sum do if (x[i]>=a)and(x[i]<=b) then inc(ans); writeln(ans); end.
T3 New New Year and Domino
传送门
http://codeforces.com/contest/611/problem/C题目大意
给定棋盘,若干询问,矩形区域内能放1x2的骨牌方案数题解
其实不是覆盖问题,就是只放一个有多少位置,要么横着放,要么竖着放,再搞个前缀和就行var w,sum1,sum11,sum2,sum22,sum:array[0..505,0..505]of longint; i,j,k,l:longint; n,m,t,a,b,c,d,ans:longint; cha:char; begin readln(n,m); for i:=1 to n do begin for j:=1 to m do begin read(cha); if cha='.' then w[i,j]:=0 else w[i,j]:=1; end; readln; end; for i:=1 to n do for j:=1 to m do begin sum[i,j]:=sum[i-1,j]+sum[i,j-1]-sum[i-1,j-1]; if (w[i,j]=0)and(w[i-1,j]=0)and(i>=2) then inc(sum[i,j]); if (w[i,j]=0)and(w[i,j-1]=0)and(j>=2) then inc(sum[i,j]); end; for i:=1 to n do for j:=2 to m do if (w[i,j]=1)or(w[i,j-1]=1) then sum2[i,j]:=sum2[i,j-1] else sum2[i,j]:=sum2[i,j-1]+1; for j:=1 to m do for i:=2 to n do if (w[i,j]=1)or(w[i-1,j]=1) then sum1[i,j]:=sum1[i-1,j] else sum1[i,j]:=sum1[i-1,j]+1; readln(t); for l:=1 to t do begin readln(a,b,c,d); ans:=0; for i:=a to c do if (w[i,b]=1)or((w[i,b-1]=1)or(b=1)) then inc(ans,sum2[i,d]-sum2[i,b-1]) else inc(ans,sum2[i,d]-sum2[i,b-1]-1); for i:=b to d do if (w[a,i]=1)or((w[a-1,i]=1)or(a=1)) then inc(ans,sum1[c,i]-sum1[a-1,i]) else inc(ans,sum1[c,i]-sum1[a-1,i]-1); writeln(ans); end; end.
T4 New Year and Ancient Prophecy
传送门
http://codeforces.com/contest/611/problem/D题目大意
给定一个序列,然后把序列切开,使切出来的数严格递增题解
DPdp[i,j]:前i个位置,最后切出来的是后j个dp[i,j]:前i个位置,最后切出来的是后j个
dp[0,j]=1dp[0,j]=1
很明显的O(N3)的DPO(N^3)的DP
dp[i,j]=dp[i−j,k] (k<j)or((x[i−j−k+1,i−j]<x[i−j+1,i])and(k=j))dp[i,j]=dp[i-j,k]~~(k
我们发现每次是在dp[i−j,k]dp[i-j,k]相当于一个前缀和的转移,所以我们维护一个sum[i,j]sum[i,j]
sum[i,j]sum[i,j]负责转移(k<j)(k的部分
当k>jk>j时一定不转移
当k=jk=j时我们要判断两个等长的字符串的大小,我们用预处理来解决这个问题
lcp:最长公共前缀lcp:最长公共前缀
我们定义lcp[i,j]为从i开始和从j开始的最长公共前缀长度lcp[i,j]为从i开始和从j开始的最长公共前缀长度
当两部分相等时lcp大于等于他俩的长度当两部分相等时lcp大于等于他俩的长度
否则我们判断lcp+1位置的字符大小即可否则我们判断lcp+1位置的字符大小即可
最后,lcp可以用O(N2)的DP处理出来lcp可以用O(N^2)的DP处理出来
lcp[i,j]=lcp[i+1,j+1] (x[i]=x[j])lcp[i,j]=lcp[i+1,j+1]~~(x[i]=x[j])
lcp[i,j]=0 (x[i]<>x[j])lcp[i,j]=0~~(x[i]<>x[j])
当然也可以后缀数组求出,,,
var lcp,sum,dp:array[0..5005,0..5005]of longint; i,j,k:longint; n,ans,tt:longint; x,a,b:ansistring; begin readln(n); readln(x); for i:=n downto 1 do for j:=i downto 1 do if x[i]=x[j] then lcp[i,j]:=lcp[i+1,j+1]+1 else lcp[i,j]:=0; for i:=1 to n do for j:=1 to n do begin if i-j<0 then begin sum[i,j]:=sum[i,j-1]; continue; end; if i-j=0 then begin dp[i,j]:=1; sum[i,j]:=(sum[i,j-1]+dp[i,j])mod 1000000007; continue; end else if x[i-j+1]='0' then begin dp[i,j]:=0; sum[i,j]:=(sum[i,j-1]+dp[i,j])mod 1000000007; continue; end; if i-2*j>=0 then begin tt:=lcp[i-j+1,i-2*j+1]; if (tt>=j)or(x[i-2*j+tt+1]>x[i-j+tt+1]) then dp[i,j]:=(dp[i,j]+sum[i-j,j-1])mod 1000000007 else dp[i,j]:=(dp[i,j]+sum[i-j,j-1]+dp[i-j,j])mod 1000000007; end else dp[i,j]:=(dp[i,j]+sum[i-j,i-j])mod 1000000007; sum[i,j]:=(sum[i,j-1]+dp[i,j])mod 1000000007; end; ans:=0; for i:=1 to n do ans:=(ans+dp[n,i])mod 1000000007; writeln(ans); end.
相关文章推荐
- ubuntu 下Linpack安装,MPI+GOTOBLAS2
- GOLANG打包
- HDU1533-Going Home 简单KM
- Good Bye 2015 C New Year and Domino(dp)
- Good Bye 2015 C. New Year and Domino 二维前缀
- Codeforces Good Bye 2015 C. New Year and Domino (预处理)
- Good Bye 2015 A. New Year and Days 签到
- Good Bye 2015 C
- Good Bye 2015 A
- 如何将DJANGO轻量级化
- django乱码问题
- go标准命令详解0.14 go env
- go标准命令详解0.13 go tool cgo
- go标准命令详解0.12 go tool pprof
- go标准命令详解0.11 go vet与go tool vet
- go标准命令详解0.10 go fix与go tool fix
- go标准命令详解0.9 go fmt与gofmt
- go标准命令详解0.8 go list
- go标准命令详解0.7 go test
- go标准命令详解0.6 go run