17.9.23B组总结

来源:互联网 发布:淘宝产品打折功能收费 编辑:程序博客网 时间:2024/06/05 10:19

17.9.23B组总结

T1

赤裸裸的一道水题(我并非大佬),用暴力就好了。

T2

考试懵逼,看完正解后恍然大悟,不要被他表面现象所迷惑,第一问就是一个最长不下降子序列。至于第二问嘛,不过反过来做一遍最长不上升子序列,取交集即可。
来一波代码

uses math;var        n,i,j,ans,w,tot,t,s:longint;        a,f,ff,b,bz:array[0..100000]of longint;function er(x:longint):longint;var        l,r,mid:longint;begin        l:=1;        r:=j;        er:=0;        while l<=r do        begin                mid:=(l+r) div 2;                if b[mid]<x then                begin                        er:=mid;                        l:=mid+1;                end                else                        r:=mid-1;        end;        inc(er);end;function ere(x:longint):longint;var        l,r,mid:longint;begin        l:=1;        r:=j;        ere:=0;        while l<=r do        begin                mid:=(l+r) div 2;                if b[mid]>x then                begin                        ere:=mid;                        l:=mid+1;                end                else                        r:=mid-1;        end;        inc(ere);end;begin        readln(n);        for i:=1 to n do                read(a[i]);        readln;        j:=0;        for i:=1 to n do        begin                if a[i]>=b[j] then                begin                        inc(j);                        b[j]:=a[i];                        f[i]:=j;                end                else                begin                        f[i]:=er(a[i]);                        b[f[i]]:=a[i];                end;        end;        s:=j;        writeln(s);        j:=0;        fillchar(b,sizeof(b),0);        b[0]:=maxlongint;        for i:=n downto 1 do        begin                if a[i]<=b[j] then                begin                        inc(j);                        b[j]:=a[i];                        ff[i]:=j;                end                else                begin                        ff[i]:=ere(a[i]);                        b[ff[i]]:=a[i];                end;        end;        for i:=1 to n do                if f[i]+ff[i]-1=s then                        inc(bz[f[i]]);        for i:=1 to n do                if (f[i]+ff[i]-1=s)and(bz[f[i]]=1) then                        write(i,' ');        writeln;end.

T3

真的改得我好辛苦好累呀,试了三种方法,终于切了此题。
网上题解(刘犇真情推荐):http://blog.csdn.net/lyd_7_29/article/details/54619437(帮别人刷访问量~)。
大致是这样的:
设f[i][j][0/1]表示当前树大小为i,任意编号都可能当根,形成最大匹配数为j,0 or 1表示匹配中有无根
一个子树时显然:

f[i+1][x][0]+=(i+1)f[i][x][1]

f[i+1][x+1][1]+=(i+1)f[i][x][0]

两边都有子树时要枚举另外一边,处理出:
s=Cii+j

当i=j时s=s/2;
t00=f[i][x][0]f[j][y][0]
t01=f[i][x][0]f[j][y][1]
t10=f[i][x][1]f[j][y][0]
t11=f[i][x][1]f[j][y][1]
接着最重要的更新答案:
f[i+j+1][x+y][0]+=(i+j+1)t11s

f[i+j+1][x+y+1][1]+=(i+j+1)(t00+t01+t10)s

记得所有除要改用逆元。
标(不要co,有害身心)

uses math;const        mo=1000000007;var        n,k,i,j,x,y:longint;        s,t00,t01,t10,t11,b:int64;        f:array[0..50,0..50,0..1]of int64;        c:array[0..100]of int64;function ff(x,y:int64):int64;var        s:int64;begin        s:=1;        while y>0 do        begin                if y and 1=1 then                        s:=s*x mod mo;                x:=x mod mo*x mod mo;                y:=y div 2;        end;        exit(s);end;begin        readln(n,k);        c[0]:=1;        for i:=1 to n do                c[i]:=c[i-1]*i mod mo;        f[0,0,0]:=1;        f[1,0,0]:=1;        b:=ff(c[2],mo-2);        for i:=1 to n-1 do        begin                for j:=0 to min(k,i div 2) do                begin                        f[i+1,j,0]:=(f[i+1,j,0]+(i+1)*f[i,j,1] mod mo) mod mo;                        f[i+1,j+1,1]:=(f[i+1,j+1,1]+(i+1)*f[i,j,0] mod mo) mod mo;                        for x:=1 to min(i,n-i-1) do                        begin                                for y:=0 to x div 2 do                                begin                                        s:=c[i+x]*ff(c[i],mo-2) mod mo*ff(c[x],mo-2) mod mo;                                        if i=x then                                                s:=s*b mod mo;                                        t00:=f[i,j,0]*f[x,y,0] mod mo;                                        t01:=f[i,j,0]*f[x,y,1] mod mo;                                        t10:=f[i,j,1]*f[x,y,0] mod mo;                                        t11:=f[i,j,1]*f[x,y,1] mod mo;                                        f[i+x+1,j+y,0]:=(f[i+x+1,j+y,0]+(i+x+1)*t11 mod mo*s mod mo) mod mo;                                        f[i+x+1,j+y+1,1]:=(f[i+x+1,j+y+1,1]+(i+x+1)*(t00+t01+t10) mod mo*s mod mo) mod mo;                                end;                        end;                end;        end;        writeln((f[n,k,1]+f[n,k,0]) mod mo*ff(n,mo-2) mod mo);end.
原创粉丝点击