17.10.8B组总结

来源:互联网 发布:samorost3 mac下载 编辑:程序博客网 时间:2024/06/11 21:32

17.10.8B组总结

T1

考试的时候脑子一团糟,随便码了一个伪暴力,数据水,居然还拿了80,QAQ。
正解其实很简单,从后往前一直逆序找,即从n..1,有多少个就用n-它的个数,即为答案。
放代码,供后人享福:

var        t,n,i,ans,j,r,jl:longint;        a,b:array[0..100000]of longint;begin        assign(input,'book.in');        reset(input);        assign(output,'book.out');        rewrite(output);        readln(t);        while t>0 do        begin                dec(t);                readln(n);                ans:=1;                for i:=1 to n do                begin                        read(a[i]);                        if a[i]=n then                                j:=i;                end;                r:=n-1;                for i:=j downto 1 do                begin                        if r=a[i] then                        begin                                dec(r);                                inc(ans);                        end;                end;                readln;                writeln(n-ans);        end;        close(input);        close(output);end.

T2

三道题中我码得最长的一道,考试先用DP,后改单调队列,可还是逃不出40分的魔咒。
正解貌似还可用单调栈,以及WZD大佬的随机数据下的暴力做法。
但我用了码量最长的单调队列+线段树,其他的还是一样DP。从码到调,两个多小时,时间呐。。。

uses math;var        n,i,s,j,l,r:longint;        p,b,f,d,bz,last,lsh,dd:array[0..150000]of longint;        t:array[0..500000,1..4]of longint;        lazy:array[0..500000]of longint;procedure make(d,l,r:longint);var        w,g:longint;begin        t[d,1]:=maxlongint;        t[d,2]:=maxlongint;        t[d,3]:=l;        t[d,4]:=r;        if l=r then                exit;        w:=(l+r) div 2;        g:=2*d;        make(g,l,w);        make(g+1,w+1,r);end;procedure cha(d:longint);begin        if (t[d,3]=t[d,4])or(lazy[d]=0) then                exit;        lazy[d*2]:=lazy[d];        lazy[d*2+1]:=lazy[d];        t[d*2,2]:=t[d*2,1]+lazy[d];        t[d*2+1,2]:=t[d*2+1,1]+lazy[d];        lazy[d]:=0;end;function find(d,l,r:longint):longint;var        mid:longint;begin        cha(d);        if (t[d,3]=l)and(t[d,4]=r) then                exit(t[d,2]);        mid:=(t[d,3]+t[d,4]) div 2;        if r<=mid then                exit(find(2*d,l,r))        else                if l>mid then                        exit(find(2*d+1,l,r));        if (r>mid)and(l<=mid) then                exit(min(find(2*d,l,mid),find(2*d+1,mid+1,r)));end;procedure ins(d,l,r,v:longint);var        mid:longint;begin        cha(d);        t[d,1]:=min(t[d,1],r);        t[d,2]:=min(t[d,2],r+v);        if t[d,3]=t[d,4] then                exit;        mid:=(t[d,3]+t[d,4]) div 2;        if l<=mid then                ins(d*2,l,r,v)        else                ins(d*2+1,l,r,v);end;procedure g(d,l,r,v:longint);var        mid:longint;begin        cha(d);        if (t[d,3]=l)and(t[d,4]=r) then        begin                lazy[d]:=v;                t[d,2]:=t[d,1]+v;                exit;        end;        mid:=(t[d,3]+t[d,4]) div 2;        if r<=mid then                g(d*2,l,r,v)        else                if l>mid then                        g(d*2+1,l,r,v)                else                begin                        g(d*2,l,mid,v);                        g(d*2+1,mid+1,r,v);                end;        t[d,2]:=min(t[d*2,2],t[d*2+1,2]);end;begin        assign(input,'array.in');        reset(input);        assign(output,'array.out');        rewrite(output);        readln(n);        for i:=1 to n do        begin                readln(p[i],b[i]);                last[i]:=max(bz[p[i]]+1,last[i-1]);                bz[p[i]]:=i;        end;        l:=1;        r:=0;        for i:=1 to n do        begin                while (l<=r)and(d[r]<=b[i]) do                        dec(r);                if l<=r then                        lsh[i]:=dd[r]                else                        lsh[i]:=0;                inc(r);                d[r]:=b[i];                dd[r]:=i;        end;        make(1,1,n);        for i:=1 to n do        begin                if lsh[i]+1<i then                        g(1,lsh[i]+1,i-1,b[i]);                ins(1,i,f[i-1],b[i]);                f[i]:=find(1,last[i],i);        end;        writeln(f[n]);        close(input);        close(output);end.

T3

这题的并查集坑啊,考试时谁又能想到正解呢,但做法真的很巧妙。
二分答案,再利用相同答案的区间和与区间并+并查集判断,最后输出答案,记得特判0。
放半标吧,要不然会有人说我是标程党的。

function get(x:longint):longint;begin        if f[x]=x then                exit(x);        f[x]:=get(f[x]);        exit(f[x]);end;function pd(x:longint):boolean;var        i,h,t,xx,yy:longint;begin        fillchar(b,sizeof(b),0);        fillchar(c,sizeof(c),0);        fillchar(f,sizeof(f),0);        for i:=1 to x do                b[i]:=a[i];        kp(1,x);        h:=0;        b[h,3]:=0;        t:=0;        for i:=1 to x do        begin                if b[i,3]<>b[h,3] then                begin                        h:=i;                        inc(t);                        c[t,1]:=b[i,1];                        c[t,2]:=b[i,2];                        c[t,3]:=b[i,1];                        c[t,4]:=b[i,2];                        continue;                end;                c[t,1]:=max(c[t,1],b[i,1]);                c[t,2]:=min(c[t,2],b[i,2]);                c[t,3]:=min(c[t,3],b[i,1]);                c[t,4]:=max(c[t,4],b[i,2]);                if c[t,1]>c[t,2] then                        exit(false);        end;        for i:=1 to n+1 do                f[i]:=i;        for i:=1 to t do        begin                xx:=c[i,1];                yy:=c[i,2]+1;                if get(xx)=get(yy) then                        exit(false);                xx:=c[i,3];                yy:=c[i,4]+1;                while get(xx)<yy do                begin                        xx:=f[xx];                        inc(f[xx]);                        inc(xx);                end;        end;        exit(true);end;
原创粉丝点击