洛谷P4884 多少个1?

D e s c r i p t o i n Descriptoin Descriptoin

求多少个1连在一起 m o d   m = k mod\ m=k mod m=k

数据范围:
0 ≤ k < m ≤ 1 0 11 0\leq k<m\leq 10^{11} 0k<m1011


S o l u t i o n Solution Solution

问题等价于 1 0 n − 1 9 ≡ k ( m o d   m ) \frac{10^n-1}9\equiv k(mod\ m) 910n1k(mod m)

两边乘9【数据没卡,但其实是不完全成立的,如果数据卡你的话得用 e x B S G S exBSGS exBSGS】,得到 1 0 n − 1 ≡ 9 k ( m o d   m ) 10^n-1\equiv 9k(mod\ m) 10n19k(mod m)

移项

1 0 n ≡ 9 k + 1 ( m o d   m ) 10^n\equiv 9k+1(mod\ m) 10n9k+1(mod m)
套板子即可


80分哈希代码(不知道哪错了,就大佬斧正)

#include
#include
#include
#define LL long long
using namespace std;LL m,k;
struct hash
{
	#define p 9999973
	int a[p],b[p];
	inline LL h(LL x){return x%p;}
	inline int find(LL x)
	{
		LL y=x%p;
		while(a[y]&&a[y]!=x) y=h(++y);
		return y;
	}
	inline void push(LL x,LL num)
	{
		int y=find(x);
		a[y]=x;
		b[y]=num;
		return;
	}
	inline int init(LL x)
	{
		int y=find(x);
		return a[y]==x?b[y]:-1;
	}
	#undef p
}h;
inline LL ksc(LL a,LL b,LL p)
{
    a%=p;b%=p;
    long long c=(long double)a*b/p;
    long long ans=a*b-c*p;
    if(ans<0) ans+=p;
    else if(ans>=p) ans-=p;
    return ans;
}
inline LL ksm(LL x,LL y,LL p)
{
	LL ans=1;
	for(;y;y>>=1,x=ksc(x,x,p)) if(y&1) ans=ksc(ans,x,p);
	return ans;
}
inline LL BSGS(LL a,LL b,LL p)
{
	a%=p;b%=p;
	if(!a) return !b?1:-1;
	if(b==1) return 0;
	LL t=ceil(sqrt(p)),val;
	for(register int j=0;j<t;j++) val=ksc(b,ksm(a,j,p),p),h.push(val,j);
	a=ksm(a,t,p);val=1;
	for(register int i=1;i<=t;i++)
	{
		val=ksc(val,a,p);
		LL j=h.init(val);
		if(j>=0&&i*t-j>=0) return i*t-j;
	}
	return -1;
}
signed main()
{
	scanf("%lld%lld",&k,&m);
	printf("%lld",BSGS(10,9*k+1,m));
}

AC C o d e Code Code

#include 
#include
#include
#include
#define LL long long
using namespace std;LL m,k;
inline LL ksc(LL a,LL b,LL p)
{
    if(a>1e9||b>1e9)
	{
        LL x=1LL<<25;
        LL L=a*(b>>25LL)%p*x%p;
        LL R=a*(b&(x-1))%p;
        return (L+R)%p;
    }
    else return a*b%p;
}
inline LL ksm(LL x,LL y,LL p)
{
	LL ans=1;
	for(;y;y>>=1,x=ksc(x,x,p)) if(y&1) ans=ksc(ans,x,p);
	return ans;
}
inline LL BSGS(LL a,LL b,LL p)
{
	a%=p;b%=p;LL val;
	if(!a) return !b?1:-1;
	if(b==1) return 0;
	map<LL,int>h;h.clear();
	LL t=ceil(sqrt(p));
	for(register int j=0;j<t;j++) val=ksc(b,ksm(a,j,p),p),h[val]=j;
	a=ksm(a,t,p);
	val=1;
	for(register int i=1;i<=t;i++)
	{
		val=ksc(val,a,p);
		LL j=h.find(val)==h.end()?-1:h[val];
		if(j>=0&&i*t-j>=0) return i*t-j;
	}
	return -1;
}
signed main()
{
	scanf("%lld%lld",&k,&m);
	printf("%lld",BSGS(10,9*k+1,m));
}

你可能感兴趣的:(HASH,BSGS,BSGS,4884,多少个1)