17.10.6B组总结
来源:互联网 发布:手机商城模板php 编辑:程序博客网 时间:2024/06/10 02:53
17.10.6B组总结
T1
完美签到题,先将问题转化为1~r中的数减去1~l-1中的数,再根据容斥原理,用递归,偶数加,奇数减,完美AC……
var n,l,r,i,j,ll,rr,len,ans:longint; a,f:array[0..20]of int64;function gcd(x,y:int64):int64;begin if x mod y=0 then exit(y); exit(gcd(y,x mod y));end;function dg(t,sum,sf:longint;h:int64):longint;begin if t>n then begin if sum>0 then inc(f[sum],sf div h); exit; end; dg(t+1,sum,sf,h); dg(t+1,sum+1,sf,h*a[t] div gcd(h,a[t]));end;function find(ss:int64):int64;var i,rr,len,s:longint;begin fillchar(f,sizeof(f),0); find:=0; dg(1,0,ss,1); for i:=1 to n do if i mod 2=1 then inc(find,f[i]) else dec(find,f[i]); exit(ss-find);end;begin readln(n,l,r); for i:=1 to n do read(a[i]); writeln(find(r)-find(l-1));end.
这题居然在今天做提高组15年初赛题目里出现了,无语O__O “…
T2
这是今天比赛里最难的题了,开始想到了50分的状压DP,无奈调不出来,只好弃疗;
正解也很简单,就直接设f[i,j]表示做到了第i行,二进制状态为j,再预处理出该状态之前的状态,轻松搞定50分。
接着发生了神奇的一幕,M在后50分中居然缩小了,于是问题就变成了两部分。我们发现其实对于一个状态i,转移到下一个状态j之后,转移的方法不会改变,于是很自然的想到了矩阵乘法。
多设一个a数组,来将每一个预处理出的前状态与现状态塞到a里面。再用快速幂搞一搞就好了,记得n很大,要用高精度除,最好压位。
大致代码:
const mo=1000000007; e=1000000000000000;type arr=array[0..32]of int64; ju=array[0..32,0..32]of int64;var n,m,i,j,k,tot:longint; s,tn,tm:ansistring; tmp:string; f:array[0..100,0..10000]of int64; jl:array[0..15000,1..2]of int64; a,ans:ju; g:arr;procedure dg(x:longint;last,now:int64);begin if x>m then exit; if x=m then begin inc(tot); jl[tot,1]:=last; jl[tot,2]:=now; end; dg(x+1,(last<<1)+1,now<<1); dg(x+1,last<<1,(now<<1)+1); dg(x+2,(last<<2)+3,(now<<2)+3);end;function did(x,y:ju):ju;var i,j,k:longint;begin fillchar(did,sizeof(did),0); for i:=0 to 1<<m do for j:=0 to 1<<m do for k:=0 to 1<<m do did[i,j]:=(did[i,j]+x[i,k]*y[k,j]) mod mo;end;procedure divv(var x:arr);var i,tt:longint;begin tt:=0; for i:=x[0] downto 1 do begin inc(x[i],tt*e); tt:=x[i] mod 2; x[i]:=x[i] div 2; if x[i]=0 then x[0]:=i-1; end;end;procedure quick(r:arr);begin fillchar(ans,sizeof(ans),0); for i:=0 to 1<<m do ans[i,i]:=1; while r[0]>0 do begin if r[1] and 1=1 then ans:=did(ans,a); a:=did(a,a); divv(r); end;end;begin readln(s); tn:=copy(s,1,pos(' ',s)-1); tm:=copy(s,pos(' ',s)+1,length(s)-pos(' ',s)); val(tm,m); dg(0,0,0); if (length(tn)<=2)or(tn='100') then begin val(tn,n); if n*m mod 2=1 then begin writeln(0); halt; end; f[0,(1<<m)-1]:=1; for i:=1 to n do for j:=1 to tot do f[i,jl[j,2]]:=(f[i,jl[j,2]]+f[i-1,jl[j,1]]) mod mo; writeln(f[n,(1<<m)-1]); halt; end; for i:=1 to tot do a[jl[i,1],jl[i,2]]:=1; fillchar(g,sizeof(g),0); tmp:=''; i:=length(tn); j:=0; while i>=1 do begin tmp:=tn[i]+tmp; inc(j); if j=15 then begin inc(g[0]); val(tmp,g[g[0]]); j:=0; tmp:=''; end; dec(i); end; if j>0 then begin inc(g[0]); val(tmp,g[g[0]]); end; quick(g); m:=(1<<m)-1; writeln(ans[m,m] mod mo);end.
T3
暴力都能过,纪中数据水呀!
正解是双向队列+栈维护,可我比赛只得了70,莫名其妙。 对了,c++有个特别好用的自带翻转函数,比正解还快。
#include<cstdlib>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;int q[5000010];int c,k,top;int main(){ scanf("%d",&c); scanf("%d",&k); while(k) { if(k==1) { int e; scanf("%d",&e); q[++top]=e; } if(k==2) { if(top<1) printf("Error: the stack is empty!\n"); else printf("%d\n",q[top]),top--; } if (k==3) { if(top<c) printf("Error: less than %d elements in the stack!\n",c); else reverse(q+1+top-c,q+1+top); } scanf("%d",&k); } return 0;}
T4
比赛打了十个表懵逼,后来蒙蒙地打了个递推上去,a掉了,听刘犇讲好像是什么奇怪的东西,懵逼 *2。
推一波式子后,发现:
答案f[n],显而易见。
记得f[1]=0;
阅读全文
1 0
- 17.10.6B组总结
- 17.10.7B组总结
- 17.10.8B组总结
- 17.10.28B组总结
- 17.8.6B组总结
- JZOJ 2017.8.6 B组总结
- 16.7.12 B组总结
- 16.7.13 B组总结
- 16.7.14 B 组总结
- 16.7.15 B组总结
- 17.1.17 B组总结
- 2017.2.11B组总结
- 17.3.25 B组总结
- 17.7.11B组总结
- 17.7.13B组总结
- 17.7.14B组总结
- JZOJ 8.7 B组总结
- JZOJ 8.8 B组总结
- 【C++学习笔记】引用
- 【末世旅行之渗透测试】局域网内字典破解3389远程桌面
- jvm和类加载
- LintCode 解题记录 17.10.5 递归
- Sourcetree 上进行git-flow功能测试(超级详细)
- 17.10.6B组总结
- 【51nod】1007 正整数分组
- 【树状数组】cal 题解
- caffe源码阅读——SyncedMemory.cpp
- 数据结构C++小笔记《2017-10-06》
- docker镜像管理命令学习
- vmware12中ubuntu15 16的vmware tools失效,导致不能复制粘贴文件以及自动适应窗口分辨率
- 【模拟】hex 题解
- 数组中重复的数