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(总结)

谢谢