数据包:http://pan.baidu.com/s/1pJNSkL9
T1:
我们先直接用矩阵快速幂暴力
首先是0维,f1=1,f2=1
然后推出下一维的f1'和f2'
下一维的f1'和f2'其实就是f1+f2+f3+....+fn和f2+f3+f4+...+fn+1
所以f1'=sn,f2'=s(n+1)-f1
所以可以klogn求出答案
但是我们做了很多相同的事情,求sn和s(n+1)的时候求出来的矩阵是一样的
所以可以是logn+k的
但是既然是一样的其实f1,f2推到f1'和f2'是可以快速幂的
于是就变成了logn+logk的了
1 const 2 h=1000000007; 3 type 4 matrix=array[1..3,1..3]of int64; 5 const 6 d:matrix=((1,0,0),(1,0,1),(0,1,1)); 7 var 8 n,k:int64; 9 t:longint; 10 a,b,c:matrix; 11 12 operator *(a,b:matrix)c:matrix; 13 var 14 i,j,k:longint; 15 begin 16 fillchar(c,sizeof(c),0); 17 for i:=1 to 3 do 18 for j:=1 to 3 do 19 for k:=1 to 3 do 20 c[i,j]:=(c[i,j]+a[i,k]*b[k,j])mod h; 21 end; 22 23 procedure main; 24 var 25 i:longint; 26 begin 27 read(n,k); 28 b:=d; 29 fillchar(a,sizeof(a),0); 30 for i:=1 to 3 do 31 a[i,i]:=1; 32 while n>0 do 33 begin 34 if n and 1=1 then a:=a*b; 35 b:=b*b; 36 n:=n>>1; 37 end; 38 b:=a*d; 39 fillchar(c,sizeof(c),0); 40 c[1,1]:=a[2,1]; 41 c[2,1]:=a[3,1]; 42 c[1,2]:=(b[2,1]-1+h)mod h; 43 c[2,2]:=b[3,1]; 44 fillchar(a,sizeof(a),0); 45 for i:=1 to 3 do 46 a[i,i]:=1; 47 while k>0 do 48 begin 49 if k and 1=1 then a:=a*c; 50 c:=c*c; 51 k:=k>>1; 52 end; 53 writeln((a[1,1]+a[2,1])mod h); 54 end; 55 56 begin 57 read(t); 58 while t>0 do 59 begin 60 dec(t); 61 main; 62 end; 63 end.
T2:
首先有一个结论,那个函数是递增的
然后我们可以证明这样一个结论
假设现在sg最大为k,那么现在最后k+1个sg组成的集合一定是0...k
若现在P[m]>=k+1,那么显然sg[m]=k+1
若现在P[m]=k,那么sg[m]=sg[m-k]
可以用数学归纳法证明
又因为maxsg<=10^5
于是就维护这个sg的序列
T3:
又是合并的思想
首先我们想一下什么情况父亲会和儿子合并(首先把不可能有收益的儿子删掉,且按最低血量限制排序)
若合并之后血量最低限制不变就一定要合并
若父亲现在没有收益就一定要合并
用可并堆或者启发式合并维护
大概就是这样,具体看solution
1 const 2 maxn=200200; 3 inf=100000000; 4 type 5 node=record 6 size,lc,rc,pay,gain:longint; 7 end; 8 var 9 first,next,last,d:array[0..maxn*2]of longint; 10 f:array[0..maxn]of node; 11 n,t,time,tot:longint; 12 13 procedure swap(var x,y:longint); 14 var 15 t:longint; 16 begin 17 t:=x;x:=y;y:=t; 18 end; 19 20 procedure insert(x,y:longint); 21 begin 22 inc(tot); 23 last[tot]:=y; 24 next[tot]:=first[x]; 25 first[x]:=tot; 26 end; 27 28 function max(x,y:longint):longint; 29 begin 30 if x>y then exit(x); 31 exit(y); 32 end; 33 34 function merge(a,b:longint):longint; 35 begin 36 if (a=0) or (b=0) then exit(a+b); 37 if f[b].pay<f[a].pay then swap(a,b); 38 f[a].rc:=merge(f[a].rc,b); 39 if f[f[a].rc].size>f[f[a].lc].size then swap(f[a].lc,f[a].rc); 40 f[a].size:=f[f[a].lc].size+f[f[a].rc].size+1; 41 exit(a); 42 end; 43 44 procedure dfs(x,fa:longint); 45 var 46 i:longint; 47 begin 48 i:=first[x]; 49 d[x]:=0; 50 while i<>0 do 51 begin 52 if last[i]<>fa then 53 begin 54 dfs(last[i],x); 55 d[x]:=merge(d[x],d[last[i]]); 56 end; 57 i:=next[i]; 58 end; 59 while (d[x]<>0) and ((f[x].pay>=f[d[x]].pay) or (f[x].gain-f[x].pay<=0)) do 60 begin 61 if f[x].gain>=f[d[x]].pay then inc(f[x].gain,f[d[x]].gain-f[d[x]].pay) 62 else 63 begin 64 f[x].pay:=f[x].pay+f[d[x]].pay-f[x].gain; 65 f[x].gain:=f[d[x]].gain; 66 end; 67 d[x]:=merge(f[d[x]].lc,f[d[x]].rc); 68 end; 69 if f[x].gain-f[x].pay<=0 then d[x]:=0 70 else d[x]:=merge(d[x],x); 71 end; 72 73 procedure main; 74 var 75 i,x,y,hp:longint; 76 begin 77 fillchar(first,sizeof(first),0); 78 tot:=0; 79 read(n,t); 80 for i:=1 to n do 81 begin 82 read(f[i].gain); 83 if f[i].gain>0 then f[i].pay:=0 84 else f[i].pay:=-f[i].gain; 85 if f[i].gain<0 then f[i].gain:=0; 86 f[i].lc:=0; 87 f[i].rc:=0; 88 f[i].size:=1; 89 end; 90 for i:=1 to n-1 do 91 begin 92 read(x,y); 93 insert(x,y); 94 insert(y,x); 95 end; 96 inc(n); 97 f[n].pay:=0; 98 f[n].gain:=inf; 99 f[n].size:=1; 100 f[n].lc:=0; 101 f[n].rc:=0; 102 insert(t,n); 103 insert(n,t); 104 dfs(1,0); 105 hp:=0; 106 while d[1]<>0 do 107 begin 108 if hp<f[d[1]].pay then break; 109 inc(hp,f[d[1]].gain-f[d[1]].pay); 110 d[1]:=merge(f[d[1]].lc,f[d[1]].rc); 111 end; 112 if hp>=inf then writeln('escaped') 113 else writeln('trapped'); 114 end; 115 116 begin 117 read(time); 118 while time>0 do 119 begin 120 dec(time); 121 main; 122 end; 123 end.