zoukankan      html  css  js  c++  java
  • JZOJ__Day 9:【普及模拟】算法学习(sfxx)

    题目描述

    自从学习了动态规划后,Famer KXP对动态规划的热爱便一发不可收拾,每天都想找点题做,一天,他找到了一道题,但是不会做,于是,他找到了你。题目如下:
    给出N个无序不重复的数,再有M个询问,每次询问一个数是否在那N个数中,若在,则ans增加2^K,K为该数在原数列中的位置。
    由于ans过大,所以只要求你输出ans mod 10^9+7。

    输入

    第一行,两个数N,M,第二行N个数,第三行M个数。

    输出

    输出最终答案。

    样例输入

    5 5
    1 3 4 6 5
    1 8 1 3 6

    样例输出

    24

    数据范围限制

    30% 0< N,M<100
    50% 0< N,M<10000
    100% 0< N,M<100000
    输入的数均在2^31 以内

    分析
    理论时间复杂度:N*logN*logN
    正解:动态规划 (骗人的)
    题目背景坑人的:
    30%可以暴力拿到;
    50%可以用二分查找或者快速幂其一得到;

    正解为二分查找+快速幂。

    程序:

    var
    a,p:array[0..100000]of int64;
    i:longint;
    n,m,ans,w,wz:int64;
    
    function f(b1,p1,k1:longint):int64;
    var
    l,t,bz:int64;
    i:longint;
    a1:array[1..32]of longint;
    begin
        l:=0;t:=p1;
        while t<>0 do
        begin
            inc(l);
            a1[l]:=t mod 2;
            t:=t div 2;
        end;
        bz:=1;
        for i:=l downto 1 do
        begin
            t:=bz*bz mod k1;
            if a1[i]=1 then bz:=b1 mod k1 *t mod k1 else bz:=t;
        end;
        exit(bz);
    end;
    
    procedure kp(l,r:longint);
    var
    i,j:longint;
    mid:int64;
    begin
        if l>=r then exit;
        i:=l;j:=r;mid:=a[(i+j) div 2];
        repeat
             while a[i]<mid do inc(i);
             while a[j]>mid do dec(j);
             if i<=j then
             begin
                 a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
                 p[0]:=p[i];p[i]:=p[j];p[j]:=p[0];
                 inc(i);dec(j);
             end;
        until i>j;
        kp(l,j);
        kp(i,r);
    end;
    
    function search(k:int64):longint;
    var
    l,r,mid:int64;
    begin
        l:=1;r:=n;
        mid:=(l+r) div 2;
        while (a[mid]<>k)and(l<=r) do
        begin
            if a[mid]>k then r:=mid-1 else l:=mid+1;
            mid:=(l+r) div 2;
        end;
        if l>r then exit(0);
        exit(mid);
    end;
    
    
    begin
        assign(input,'sfxx.in');
        reset(input);
        assign(output,'sfxx.out');
        rewrite(output);
        readln(n,m);
        for i:=1 to n do
        begin
            read(a[i]);
            p[i]:=i;
        end;
        kp(1,n);
        readln;
        ans:=0;
        for i:=1 to m do
        begin
            read(w);
            wz:=search(w);
            if wz>0 then ans:=ans+f(2,p[wz],1000000007);
        end;
        write(ans mod 1000000007);
        close(input);
        close(output);
    end.
  • 相关阅读:
    pywin32解析office文档
    解决NGUI自动被设置LYAER
    ngui的tween的tweenFactor属性
    ngui中 代码调用按钮事件(后来改成了按钮绑定键盘..)
    unity调用摄像头的方法
    坐标转换,这次是反过来,屏幕坐标转换成世界坐标
    unity5.3 安卓广告插件打包出错的理解
    从世界坐标转换成ui的rect坐标的方法
    关于unity碰撞检测器的用法
    测试第一篇标题
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/9500083.html
Copyright © 2011-2022 走看看