3.算法学习(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 以内
正解
快排+二分+快速幂
AC代码
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,m,k,l,r;
long long b,s;
struct stu
{
int num;
long long ans;
}a[100005];
bool cmp(stu x,stu y)//快排
{
return x.ans<y.ans;
}
void ef(long long x)//二分
{
k=0;
l=1;
r=n;
while(l<=r)
{
int mm=(l+r)/2;
if(a[mm].ans==x){k=a[mm].num;break;}
if(a[mm].ans>x)r=mm-1;
else l=mm+1;
}
}
long long ksm(long long x)//快速幂
{
if(x==0)return 1;
if(x%2==0)
{
long long mm=ksm(x/2)%1000000007;
return mm*mm%1000000007;
}
else return 2*ksm(x-1)%1000000007;
}
int main()
{
freopen("sfxx.in","r",stdin);
freopen("sfxx.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i].ans;
a[i].num=i;
}
sort(a+1,a+n+1,cmp); //快排
for(int j=1;j<=m;j++)
{
cin>>b;
ef(b);//二分查找b
if(k!=0)
{
s+=ksm(k); //快速幂
s=s%1000000007;//%1000000007
}
}
cout<<s%1000000007;
return 0;
}
下面附本次比赛的其他题目
2020.02.19普及C组模拟赛8(第一题)
2020.02.19普及C组模拟赛8(第二题)
2020.02.19普及C组模拟赛8(第三题)
2020.02.19普及C组模拟赛8(第四题)
2020.02.19普及C组模拟赛8(总结)