2020.02.19普及C组模拟赛8(第三题)

3.算法学习(sfxx)

题目描述ios

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

输入算法

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

输出学习

输出最终答案。spa

样例输入.net

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

样例输出xml

24blog

数据范围限制

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

谢谢