hnoi2012 (bzoj2727~2734)
来源:互联网 发布:音轨软件安卓 编辑:程序博客网 时间:2024/05/16 23:44
题目就不贴了,自己看吧。
这套题每道题如果会做的话写代码的过程真是轻松加愉快……湖南人出的题似乎都是这样……真有水平……
hnoi2012 day1:
bzoj2727 双十字 cross
要求我们统计双十字的个数
r*c<=10^6
所以我们可以扫一遍整个矩阵- -
因为竖线只有一条,所以以其为主线来考虑
首先我们可以线性处理出来每个点最多向左向右延伸多少
考虑一个点作为下端的情况有多少种,即是他以上有多少个“土”
那我们考虑以一个点为双十字下面那根横线,能形成多少个“土”
设这个为点最多向两边延伸长度为len,c[i]为它以上最多向两边延伸长度i的图形的个数
就是说这样的
(
*
***
*
*
***
)
那么我们这一行长度为2~len
形成“土”的个数显然为(len-1)*c[1]+((len-1)+(len-2))*c[2]..+((len-1)+..+1)*c[len-1]+((len-1)+..+1)*(c[len]+..+c[maxlen]) (长度大于等于他的等价于比他短1的)
这个怎么算呢……
显然等价于len*(1*c[1]+2*c[2]+..(len-1)*c[len-1])-(1*c[1]+(1+2)*c[2]+(1+2+3)*c[3]+..+(1+..+(len-1))*c[len-1])+(1+..+(len-1))*(c[len]+..c[maxlen])
…………
开三个树状数组好了
虽然推导有点麻烦,但是写还是很好写的,因为只用写个树状数组
bzoj2728 与非 nand
= =比较烦的一道题
首先玩下nand
发现这个东西好神啊,可以模拟出来not、and、or、xor,有了这些常用运算,
然后我们把n个数写成二进制数
比如
(7)2=111
(5)2=101
(3)2=011
然后我们竖着看……如果有两列完全相同,那么我们是没法让造出来的数这两位不同的
为什么呢……显而易见吧……位运算跟别的位没有关系两位等价就不能不相同
实际上没有两位必须等价的话,我们可以nand出任意数
也很好证明
既然有or运算,那么我们只要做出来各种只有一位为1,其他都为0的即可造出所有数
那么我们让某位为1,其他位为该如何操作……
可以对这n个数中这一位为0进行取反,然后把n个数and起来,如果其他位列跟着一列不同,其他位必然为0……因为这位全是1
知道了这个结论接下来就十分好做了,数位dp就行了
bzoj2729 排队 queue
组合数学题,比较简单吧
因为男生没有限制,所以先排男生,用n!种排列方式
这样就有n+1个缝隙可供我们放老师和女生
可以分情况讨论
两个老师在同一个缝隙中,这时候两个老师中间必须有一个女生,情况有A(n+1,1)*m*A(n+2,m-1)种
两个老师不在同一个缝隙中,情况有A(n+1,2)*A(n+3,m)种
所以答案为n!(A(n+1,1)*m*A(n+2,m-1)+A(n+1,2)*A(n+3,m))
显然答案会爆任意数据类型……需要高精度
bzoj2730 矿场搭建 mining
思考一下可以发现,只有割点崩塌才会出现问题,不然不影响图的连通性……
所以把割点全部删除以后,图会分成几个联通块
显然的,只跟一个割点相连的联通块内必须放一个出口,所以答案就是只跟一个割点相连的联通块大小之积
…………
实际上还有一种特殊情况……
图没割点……
放一个出口就够了?
显然不够,出口塌了怎么办……所以任意选两个点做为出口都行
bzoj2731 三角形覆盖问题 triangle
这题实际上有稳定算法……
不过感觉比较麻烦就写了个跑得比较快的爆搞……实际上应该比稳定算法还快,数据似乎是随机的
显然可以一行一行求面积
一行的面积=(上一行计算新出现的三角形的覆盖长度+这一行不算新出现的三角形的覆盖长度)/2
…………一行一行扫好了
怎么求被覆盖的长度呢……
数轴比较短啊……记录每一段被覆盖了多少次很容易求出来啊……
每一段覆盖了多少次怎么知道……?加三角形的时候爆搞啊……升高一行减掉当前的三角形小时的部分啊
这样据说可以过80分
但是说了这个比稳定算法还快,所以加个优化……
暴力判下新加入的三角形是不是在当前某个三角形内部,在的话不加
…………
ac了…………
bzoj2732 射箭 archery
因为抛物线过原点可得抛物线方程y=ax^2+bx
对于某个靶子x,y1,y2
可得y1<=ax^2+bx<=y2
把ab当成x、y就是两个半平面
可以求半平面交了
一条一条加入半平面如果半平面为空就结束
似乎又是随机数据……n^2做即可
还有个什么随机增量算法……期望O(n)……不懂
这个牵扯到大量实数运算,eps需要设到1e-16
bzoj2733 永无乡neverland
简化一下题意
有两种操作
1、求一个集合的第k大的数是哪个
2、将两个集合并起来
很容易想到平衡树……但是如何合并两颗平衡树
这用到了平衡树的启发式合并
启发式合并……听起来很高端……实际上就是合并两棵树的时候把小的树里的元素一个一个塞进大的树
…………
显然,复杂度最坏nlog^2n
bzoj2734 集合选数 set
首先考虑一下互相的约束
可以发现,只有2^i*3^j*x会互相制约
那么1~n的数就被划分成了几个互相独立的系统
方案数就是各系统方案数之积
问题转化成了求一个系统的方案数
观察一下x=1的情况
9 18 36
3 6 12
1 2 4
可以按2^i次方划分成一列一列
显然,一行不会超过11个元素(3^11>10^5)
一个数选择的话,相邻的四个数都不能选
显然可以状态压缩动态规划
复杂度不太好算……但是能很快通过
我最初的想法是把这个矩阵斜着看……发现状态很多,而且转移很慢
实际上这道题在matrix67的博客上有讲过
program bzoj2727;const maxn=1000000009;var z,ans,tot,now,x,y,r,c,n,i,j,k,o:longint; s,tree:array [0..2,0..1200001] of longint; dl,w:array [0..1200001] of longint; map:array [0..1200001] of boolean; function lowbit (x:longint):longint;inline;begin exit(x xor (x and (x-1)));end;procedure insert (p,o,x:longint);inline;begin if x=0 then exit; p:=int64(p)*s[o,x] mod maxn; while x<=c do begin tree[o][x]:=(tree[o][x]+p) mod maxn; x:=x+lowbit(x); end;end;function find (o,x:longint):longint;inline;var ans:longint;begin ans:=0; while x>0 do begin ans:=(ans+tree[o][x]) mod maxn; x:=x-lowbit(x); end; exit(ans);end;begin read(r,c); read(n); for i:=1 to n do begin read(x,y); map[x*c-c+y]:=true; end; for i:=1 to r do begin now:=1; for j:=1 to c do if map[i*c-c+j] then now:=j+1 else w[i*c-c+j]:=j-now; now:=c; for j:=c downto 1 do if map[i*c-c+j] then now:=j-1 else if now-j<w[i*c-c+j] then w[i*c-c+j]:=now-j; end; for i:=1 to c do s[0,i]:=1; for i:=1 to c do s[1,i]:=i; for i:=1 to c do s[2,i]:=int64(i+1)*i div 2 mod maxn; for j:=1 to c do begin for o:=2 to tot-1 do for k:=0 to 2 do insert(-o+1,k,w[dl[o]]); tot:=0; z:=0; for i:=1 to r do if map[i*c-c+j] then begin for o:=2 to tot-1 do for k:=0 to 2 do insert(-o+1,k,w[dl[o]]); tot:=0; z:=0; end else begin ans:=(ans+z) mod maxn; inc(tot); dl[tot]:=i*c-c+j; if w[dl[tot]]>1 then begin k:=int64(w[dl[tot]])*find(1,w[dl[tot]]-1) mod maxn; k:=(k-find(2,w[dl[tot]]-1)) mod maxn; k:=(k+(find(0,c)-find(0,w[dl[tot]]-1))*(int64(w[dl[tot]]-1)*w[dl[tot]]) div 2 mod maxn) mod maxn; z:=(z+k) mod maxn; end; if (tot>=3)and(w[dl[tot-1]]>0) then for k:=0 to 2 do insert(tot-2,k,w[dl[tot-1]]); end; end; ans:=(ans+maxn) mod maxn; writeln(ans);end.
program bzoj2728;type st=array [0..1001] of boolean;const one:int64=1;var n,i,j,k:longint; l,r:int64; a:array [0..1001] of int64; eve:array [0..60] of st; count,dl,fa:array [0..60] of longint;procedure swap (var a,b:longint);inline;begin if a=b then exit; a:=a xor b; b:=a xor b; a:=a xor b;end;function over (a,b:st):boolean;inline;var i:longint;begin for i:=1 to n do if a[i]>b[i] then exit(true) else if a[i]<b[i] then exit(false); exit(false);end;function calc (n:int64):int64;var i:longint; ans:int64;begin if n<0 then exit(0); ans:=0; for i:=k-1 downto 0 do begin if n and (one shl i)<>0 then if fa[i]=0 then ans:=ans+(one shl (count[i]-1)) else if n and (one shl fa[i])=0 then ans:=ans+(one shl count[i]); if fa[i]<>0 then if (n and (one shl i)) shr i <> (n and (one shl fa[i])) shr fa[i] then break; end; if (fa[i]=0)or((fa[i]<>0)and(n and (one shl i) shr i=n and (one shl fa[i]) shr fa[i])) then inc(ans); exit(ans);end;begin read(n,k,l,r); if l>(one shl k)-1 then begin writeln(0); halt; end; if r>=(one shl k) then r:=(one shl k)-1; for i:=1 to n do read(a[i]); for i:=0 to k - 1 do for j:=1 to n do eve[i][j]:=(a[j] and (one shl i))=0; for i:=1 to k do dl[i]:=i-1; for i:=1 to k do for j:=i+1 to k do if (over(eve[dl[i]],eve[dl[j]]))or ((not over(eve[dl[i]],eve[dl[j]]))and(not over(eve[dl[j]],eve[dl[i]]))and(dl[i]<dl[j])) then swap(dl[i],dl[j]); for i:=2 to k do if (not over(eve[dl[i]],eve[dl[i-1]]))and(not over(eve[dl[i-1]],eve[dl[i]])) then fa[dl[i]]:=dl[i-1]; if fa[0]=0 then count[0]:=1 else count[0]:=0; for i:=1 to k-1 do begin count[i]:=count[i-1]; if fa[i]=0 then inc(count[i]); end; writeln(calc(r)-calc(l-1));end.
program bzoj2729;type gj=array [0..100001] of longint;varn,m,i,j,k:longint; ans,temp:gj;procedure mul (var a:gj; b:longint);inline;var i:longint;begin for i:=a[0] downto 1 do a[i]:=a[i]*b; i:=1; while (i<=a[0])or(a[i]>0) do begin a[i+1]:=a[i+1]+a[i] div 10; a[i]:=a[i] mod 10; inc(i); end; dec(i); a[0]:=i;end;procedure plus (var a,b:gj);inline;var i,k:longint;begin if a[0]>b[0] then k:=a[0] else k:=b[0]; for i:=1 to k do begin a[i]:=a[i]+b[i]; a[i+1]:=a[i+1]+a[i] div 10; a[i]:=a[i] mod 10; end; if a[k+1]<>0 then inc(k); a[0]:=k;end;begin read(n,m); if (n=0)and(m=0) then begin writeln(0); exit; end; temp[0]:=1; temp[1]:=1; mul(temp,n+1); mul(temp,2); mul(temp,m); for i:=n+2 downto n+2-m+2 do mul(temp,i); ans:=temp; fillchar(temp,sizeof(temp),0); temp[0]:=1; temp[1]:=1; mul(temp,n+1); mul(temp,n); for i:=n+3 downto n+3-m+1 do mul(temp,i); plus(ans,temp); for i:=2 to n do mul(ans,i); for i:=ans[0] downto 1 do write(ans[i]); writeln;end.
program bzoj2730;var ans:int64; all,w,tot,s,t,max,n,i,j,k:longint; dd,count,belong,dfn,low,root,fa:array [0..201] of longint; yes,divide:array [0..201] of boolean; point,next:array [0..1001] of longint;procedure connect (u,v:longint);inline;begin inc(tot); point[tot]:=v; next[tot]:=root[u]; root[u]:=tot;end;procedure dfs (now:longint);var i,k:longint;begin inc(tot); dfn[now]:=tot; low[now]:=tot; i:=root[now]; k:=0; while i<>0 do begin if point[i]<>fa[now] then if dfn[point[i]]=0 then begin inc(k); fa[point[i]]:=now; dfs(point[i]); if low[point[i]]<low[now] then low[now]:=low[point[i]]; if (now<>1)and(low[point[i]]>=dfn[now]) then divide[now]:=true; if (now=1)and(k>1) then divide[now]:=true; end else if dfn[point[i]]<low[now] then low[now]:=dfn[point[i]]; i:=next[i]; end; dec(tot);end;procedure search (now:longint);var i:longint;begin inc(count[tot]); yes[now]:=true; belong[now]:=tot; i:=root[now]; while i<>0 do begin if (not yes[point[i]])and(not divide[point[i]]) then search(point[i]); i:=next[i]; end;end;begin w:=0; repeat read(n); if n=0 then break; max:=0; fillchar(root,sizeof(root),0); for i:=1 to n do begin read(s,t); if t>max then max:=t; connect(s,t); connect(t,s); end; tot:=0; fillchar(divide,sizeof(divide),false); fillchar(dfn,sizeof(dfn),0); dfs(1); fillchar(yes,sizeof(yes),false); fillchar(count,sizeof(count),0); tot:=0; for i:=1 to max do if (not yes[i])and(not divide[i]) then begin inc(tot); search(i); end; inc(w); write('Case ',w,': '); if tot=1 then begin writeln(2,' ',max*(max-1) div 2); continue; end; fillchar(dd,sizeof(dd),0); for i:=1 to max do if divide[i] then begin fillchar(yes,sizeof(yes),false); k:=root[i]; while k<>0 do begin if (not divide[point[k]])and(not yes[belong[point[k]]]) then begin yes[belong[point[k]]]:=true; inc(dd[belong[point[k]]]); end; k:=next[k]; end; end; all:=0; ans:=1; for i:=1 to tot do if dd[i]=1 then begin inc(all); ans:=ans*count[i]; end; writeln(all,' ',ans); until false;end.
program bzoj2731;var ans:double; max,h,len,now,tot,n,i,j,k:longint; dl,next,last,x,y,d:array [0..10001] of longint; count:array [0..2000001] of longint; ok:boolean;procedure swap (var a,b:longint);inline;begin if a=b then exit; a:=a xor b; b:=a xor b; a:=a xor b;end;procedure qsort (s,e:longint);var i,j,k:longint;begin if s>=e then exit; i:=s; j:=e; k:=y[dl[(s+e) div 2]]; while i<=j do begin while y[dl[i]]<k do inc(i); while y[dl[j]]>k do dec(j); if i>j then break; swap(dl[i],dl[j]); inc(i); dec(j); end; qsort(s,j); qsort(i,e);end;begin read(n); for i:=1 to n do begin read(x[i],y[i],d[i]); dl[i]:=i; if y[i]+d[i]>max then max:=y[i]+d[i]; end; qsort(1,n); next[0]:=10001; last[10001]:=0; len:=0; h:=y[dl[1]]; i:=1; while h<=max do begin now:=len; k:=next[0]; while k<>10001 do begin dec(count[x[k]+d[k]-(h-y[k])]); if count[x[k]+d[k]-(h-y[k])]=0 then dec(now); if h=y[k]+d[k] then begin next[last[k]]:=next[k]; last[next[k]]:=last[k]; end; k:=next[k]; end; ans:=ans+(now+len)/2; len:=now; while (i<=n)and(y[dl[i]]=h) do begin ok:=true; k:=next[0]; while k<>10001 do begin if (x[k]<=x[dl[i]])and(x[dl[i]]+d[dl[i]]<=x[k]+d[k]-(h-y[k])) then begin ok:=false; break; end; k:=next[k]; end; if d[dl[i]]=0 then ok:=false; if ok then begin last[next[0]]:=dl[i]; next[dl[i]]:=next[0]; last[dl[i]]:=0; next[0]:=dl[i]; for j:=x[dl[i]] to x[dl[i]]+d[dl[i]]-1 do begin if count[j]=0 then inc(len); inc(count[j]); end; end; inc(i); end; inc(h); end; writeln(ans:0:1);end.
program bzoj2732;const eps:extended=1e-16; inf:extended=9999999999;type point= record x,y:extended; end;var ans,o,n,i,j,k:longint; tot:array [0..1] of longint; x,y1,y2:array [0..100001] of longint; dl:array [0..1,0..100001] of point;function get (x1,y1,x2,y2,k2,b2:extended):point;var k1,b1:extended; ans:point;begin if abs(x1-x2)<=eps then begin ans.x:=x1; ans.y:=x1*k2+b2; exit(ans); end; k1:=(y1-y2)/(x1-x2); b1:=y1-x1*k1; ans.x:=(b1-b2)/(k2-k1); ans.y:=ans.x*k1+b1; exit(ans);end;procedure meet (k,b:extended;p:longint);var i,j:longint;begin o:=1-o; tot[o]:=0; for i:=1 to tot[1-o] do begin if dl[1-o,i].y*p>=(dl[1-o,i].x*k+b)*p then begin inc(tot[o]); dl[o,tot[o]]:=dl[1-o,i]; end; j:=i mod tot[1-o] + 1; if (dl[1-o,i].y*p>(dl[1-o,i].x*k+b)*p)xor(dl[1-o,j].y*p>(dl[1-o,j].x*k+b)*p) then begin inc(tot[o]); dl[o,tot[o]]:=get(dl[1-o,i].x,dl[1-o,i].y,dl[1-o,j].x,dl[1-o,j].y,k,b); end; end;end;begin read(n); for i:=1 to n do read(x[i],y1[i],y2[i]); tot[o]:=4; dl[o,1].x:=-inf; dl[o,1].y:=0; dl[o,2].x:=-inf; dl[o,2].y:=inf; dl[o,3].x:=inf; dl[o,3].y:=inf; dl[o,4].x:=inf; dl[o,4].y:=0; for i:=1 to n do begin ans:=i; meet(-x[i],y1[i]/x[i],1); meet(-x[i],y2[i]/x[i],-1); if tot[o]<=2 then begin ans:=i-1; break; end; end; writeln(ans);end.
program bzoj2733;var o,u,v,n,m,q,i,j,k:longint; ch:char; fa,tot,left,right,heap:array [0..200001] of longint; a,father,sum:array [0..100001] of longint;procedure swap (var a,b:longint);inline;begin if a=b then exit; a:=a xor b; b:=a xor b; a:=a xor b;end;function root (now:longint):longint;begin if father[now]=0 then exit(now); father[now]:=root(father[now]); exit(father[now]);end;procedure rotate (son:longint);inline;var mot:longint;begin mot:=fa[son]; fa[son]:=fa[mot]; if fa[mot]<>0 then if left[fa[mot]]=mot then left[fa[mot]]:=son else right[fa[mot]]:=son; fa[mot]:=son; if left[mot]=son then begin tot[mot]:=tot[mot]-tot[son]-1; left[mot]:=right[son]; if right[son]<>0 then fa[right[son]]:=mot; right[son]:=mot; end else begin tot[son]:=tot[son]+tot[mot]+1; right[mot]:=left[son]; if left[son]<>0 then fa[left[son]]:=mot; left[son]:=mot; end;end;procedure insert (now:longint);inline;var i:longint;begin heap[now]:=random(maxlongint); i:=o; repeat if a[i]>a[now] then if left[i]=0 then begin left[i]:=now; break; end else i:=left[i] else if right[i]=0 then begin right[i]:=now; break; end else i:=right[i] until false; tot[now]:=0; fa[now]:=i; left[now]:=0; right[now]:=0; i:=now; repeat if left[fa[i]]=i then inc(tot[fa[i]]); i:=fa[i]; until fa[i]=0; while heap[now]>heap[fa[now]] do rotate(now); if fa[now]=0 then o:=now;end;procedure dfs (now:longint);begin if left[now]<>0 then begin fa[left[now]]:=0; dfs(left[now]); left[now]:=0; end; if right[now]<>0 then begin fa[right[now]]:=0; dfs(right[now]); right[now]:=0; end; insert(now);end;procedure link (u,v:longint);var i:longint;begin u:=root(u); v:=root(v); if u=v then exit; if sum[u]>sum[v] then swap(u,v); father[u]:=v; sum[v]:=sum[u]+sum[v]; while fa[u]<>0 do u:=fa[u]; while fa[v]<>0 do v:=fa[v]; o:=v; dfs(u);end;function find (now,k:longint):longint;inline;begin repeat if tot[now]+1=k then exit(now) else if tot[now]+1<k then begin k:=k-tot[now]-1; now:=right[now]; end else now:=left[now]; until false;end;begin heap[0]:=maxlongint; read(n,m); for i:=1 to n do read(a[i]); for i:=1 to n do sum[i]:=1; for i:=1 to m do begin read(u,v); link(u,v); end; readln(q); for i:=1 to q do begin readln(ch,u,v); if ch='Q' then begin u:=root(u); if sum[u]<v then begin writeln(-1); continue; end; while fa[u]<>0 do u:=fa[u]; writeln(find(u,v)); end else link(u,v); end;end.
program bzoj2734;const modu=1000000001;var o,ans,n,i,j,k:longint; thr,two:array [0..17] of longint; tot:array [0..1] of longint; dl,f:array [0..1,0..2048] of longint; yes:array [0..100001] of boolean;function calc (w:longint):longint;inline;var ans,i,j,k:longint;procedure dfs (x,y,fob,stu,plus:longint);var i:longint;begin if w*two[x]*thr[y]>n then begin if f[o][stu]=0 then begin inc(tot[o]); dl[o][tot[o]]:=stu; end; f[o][stu]:=(f[o][stu]+plus) mod modu; exit; end; dfs(x,y+1,fob,stu,plus); if fob and two[y] = 0 then dfs(x,y+2,fob,stu or two[y],plus);end;begin o:=0; tot[o]:=1; dl[o][1]:=0; f[o][0]:=1; i:=-1; while tot[o]>0 do begin inc(i); for j:=0 to 11 do if int64(w)*two[i]*thr[j]>n then break else yes[int64(w)*two[i]*thr[j]]:=true; o:=1-o; fillchar(f[o],sizeof(f[o]),0); tot[o]:=0; for j:=1 to tot[1-o] do if w*two[i]<=n then dfs(i,0,dl[1-o,j],0,f[1-o,dl[1-o,j]]); end; o:=1-o; ans:=0; for i:=1 to tot[o] do ans:=(ans+f[o][dl[o,i]]) mod modu; exit(ans);end;begin two[0]:=1; for i:=1 to 18 do two[i]:=two[i-1]*2; thr[0]:=1; for i:=1 to 12 do thr[i]:=thr[i-1]*3; ans:=1; read(n); for i:=1 to n do if not yes[i] then ans:=int64(ans)*calc(i) mod modu; writeln(ans);end.
- hnoi2012 (bzoj2727~2734)
- bzoj2727: [HNOI2012]双十字
- 2734: [HNOI2012]集合选数
- bzoj 2734 [HNOI2012]集合选数 dp
- BZOJ 2734: [HNOI2012]集合选数
- bzoj 2734: 2734: [HNOI2012]集合选数 (状压DP)
- BZOJ 2734 HNOI2012 集合选数 状压DP
- BZOJ 2734 [HNOI2012]集合选数 状压+思路
- 【BZOJ 2734】[HNOI2012]集合选数 状压dp
- BZOJ 2734: [HNOI2012]集合选数 乱搞DP
- (bzoj 2734 [HNOI2012]集合选数)<状压DP>
- bzoj 2734: [HNOI2012]集合选数 状压dp
- HNOI2012 bless
- [HNOI2012]archery
- [HNOI2012]射箭
- [HNOI2012]排队
- 【HNOI2012】 永无乡
- 【HNOI2012】射箭
- Python如何使用urllib2获取网络资源
- 链表的使用 (usage of Linked list)
- 开源中最好的Web开发的资源
- RHEL5启用使用xdmcp的一些注意事项。
- WordPress蜘蛛爬行记录教程
- hnoi2012 (bzoj2727~2734)
- vi指令說明(完整版)
- POJ 1961 KMP
- 第二章
- 压力测试衡量CPU的三个指标:CPU Utilization、Load Average和Context Switch Rate
- 高质量C++编程_第8章_C++函数的高级特性(2)
- 去掉win7快捷方式
- GCD之dispatch queue
- 建立以点开头的文件夹