题目描述
自从学习了动态规划后,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*logN*logN
题目背景坑人的:
30%可以暴力拿到;
50%可以用二分查找或者快速幂其一得到;
正解为二分查找+快速幂。
程序
#include <iostream>
#include <cstdio>
using namespace std;
long long i,j,k,n,m,ans,z,a[100001],b[100001],c[100001];
void qsort(long long l,long long r)
{
if (l>=r) return;
i=l; j=r;
long long mid=a[(l+r)/2];
do
{
while (a[i]<mid) i++;
while (a[j]>mid) j--;
if (i<=j)
{
a[0]=a[i]; a[i]=a[j]; a[j]=a[0];
b[0]=b[i]; b[i]=b[j]; b[j]=b[0];
i++; j--;
}
}
while (i<=j);
qsort(l,j);
qsort(i,r);
}
int found(long long x,long long y)
{
int m=x+(y-x)/2;
if (a[m]==k)
return m;
if (a[m]>k)
return found(x,m-1);
if (a[m]<k)
return found(m+1,y);
}
int main()
{
freopen("sfxx.in","r",stdin);
freopen("sfxx.out","w",stdout);
cin>>n>>m;
b[0]=1;
for (i=1; i<=n; i++)
{
cin>>a[i];
b[i]=(b[i-1]*2)%1000000007;
}
qsort(1,n);
for (i=1; i<=m; i++)
{
cin>>k;
if ((k>=a[1])&&(k<=a[n]))
{
ans=(ans+b[found(1,n)])%1000000007;
}
}
cout<<ans<<endl;
fclose(stdin);
fclose(stdout);
}