在纪中的第八天,2017-7-14 总结:

来源:互联网 发布:假面骑士wizard知乎 编辑:程序博客网 时间:2024/06/05 03:09


2163. 【2017.7.12普及】算法学习 (File IO): input:sfxx.in output:sfxx.out时间限制: 1000 ms 空间限制: 262144 KB 具体限制 题目描述 自从学习了动态规划后,Famer KXP对动态规划的热爱便一发不可收拾,每天都想找点题做,一天,他找到了一道题,但是不会做,于是,他找到了你。题目如下: 给出N个无序不重复的数,再有M个询问,每次询问一个数是否在那N个数中,若在,则ans增加2^K,K为该数在原数列中的位置。由于ans过大,所以只要求你输出ans mod 10^9+7。输入第一行,两个数N,M,第二行N个数,第三行M个数。输出 输出最终答案。样例输入5 51 3 4 6 51 8 1 3 6样例输出24 数据范围限制30% 0《N,M《10050% 0,N,M《10000100% 0《N,M《100000输入的数均在2^31 以内解: 这题快速幂加二分查找。 也可以打表加二分,反正都是满分。打表需要打完所有的可能;既2的100以内的次方。快速幂就是一种神奇的算法。。。

 

var

        l,r,n,i,j,m,mid,p,ans:longint;

        a:array[1..100000,1..2]of longint;

        s:array[0..100000]of longint;procedure  qsort(x,y:longint);var

i,j,mid: longint;

        t:array[1..2]of longint;begin

i:=x;

j:=y;

mid:=a[x,1];

repeat

while mid<a[j,1]do dec(j);

while mid>a[i,1]do inc(i);

if i<=jthen

begin

t:=a[i];

a[i]:=a[j];

a[j]:=t;

inc(i);

dec(j);

end;

until i>j;

if i<ythen qsort(i,y);

        if x<jthen qsort(x,j);end;procedure aa;begin

        for i:=1 to mdo

        begin

                read(p);

                l:=1;

                r:=n;

                while l<rdo

                begin

                        mid:=(l+r)div 2;

                        if a[mid,1]>=pthen r:=mid

                        else l:=mid+1;

                end;

                if a[l,1]=pthen ans:=(ans+s[a[l,2]])mod 1000000007;

        end;end;begin

        assign(input,'sfxx.in');

        reset(input);

        assign(output,'sfxx.out');

      rewrite(output);

        readln(n,m);

        s[0]:=1;

        for i:=1 to ndo

        begin

                read(a[i,1]);

                a[i,2]:=i;

                s[i]:=(s[i-1]*2)mod 1000000007;

        end;

        qsort(1,n);

    aa;

        writeln(ans);end.

 

 

 

 

本题不提供打表程序(不解释/滑稽)。今天又只写了一题,不过我分享一种算法。并查集: 我应该学过,BUT啦啦啦。我忘了。。并查集是一种树型的数据结构,用于处理一些不相交集合的合并问题。 (这句话,我承认不是我想的,是复制来的,不过说的很有道理。en); 并查集的主要操作有:

  1-合并个集合

2-查找一个单位;

3-压缩路径。

有三种操作:

1:合并两个集合:

procedure hb(c,p:longint);//两个集合的合并处

var

hong:longint;

lan:longint;

begin

hong:=getfather(c);

lan:=getfather(p); father[hong]:=father(lan);

end;

 其实这也不算是完全合并,时间复杂度就省在只更新一个点。而要注意的是,getfather是一个程序名,Pascal不会自带。

procedure getfather(x:longint);

begin

if father[x]=0 then getfather:=x else begin

getfather:=getfather(father[x]); father[x]:=getfather;

 end;

 end; 不知道有没有错误,毕竟我才手打出来,(我一定会认真检查程序!/斜眼笑);如果某位大神路过请看看啊啦啦啦。 接着是查找(仅仅判断在不在同一列(呸,好像叫集合吧啦啦)!!!):

function cz(x,y:longint):boolean;

begin

if getfather(x)=getfather(y)

then exit(true) //判断在不在同一个集合里面。 else exit(false); //exit(XXXX)‘xxxx’就是退出时函数所带得值。 end; 大致是这样的。。。。 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

可能排版有问题,因为这个编辑器,咳咳。。。***