求助QAQ,#1和#5 WA
  • 板块P1762 偶数
  • 楼主export
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/7/29 20:52
  • 上次更新2023/10/27 17:47:40
查看原帖
求助QAQ,#1和#5 WA
292176
export楼主2022/7/29 20:52

思路是直接推公式,
得到前n行的奇数个数
若 n=2^k + 2^(k-1) + … + 2^1 + 2^0
则 个数为

num=3^k * 2^0 + 3^(k-1) * 2^1 + 3^(k-2) * 2^2 +… + 3^0 * 2^m

(m表示 项数-1)

其他点都能过,但是#1和#5给WA了QnQ

求dalao指点指点 %%%

#include<iostream>
#include<cmath>
using namespace std;
long long t,n,m,x,y,ans,c,p=1000003;
long long total,wn,ji;
long long p3[1000],p2[1000];
bool w[10000000];
void pow3(long long n){		//提前算出3^0到3^n
	long long s=1;
	for(register int i=0;i<=n;i++,s*=3){
		s%=p;
		p3[i]=s;
	}
}
void pow2(long long n){		//提前算出2^0到2^n 
	long long s=1;
	for(register int i=0;i<=n;i++,s*=2){
		s%=p;
		p2[i]=s;	
	}
}
							//扩欧 
long long exgcd(long long a,long long b,long long &x,long long &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	else{
		long long gcd=exgcd(b,a%b,x,y);
		long long t=x;
		x=y;
		y=t-a/b*y;
		return gcd;
	}
}

int main(){
	scanf("%lld",&n);
	exgcd(2,p,x,y);			//算出2在mod p下的乘法逆元 
	while(x<0) x+=p;
	total=n%p*(n+1)%p*x%p;	//算出前n行的数的个数 
	while(n>0){				//用bool数组储存n的二进制形式 
		w[wn++]=n%2;
		n/=2;
	}
	pow2(wn);				
	pow3(wn);
	t=0;
	for(register int i=wn;i>=0;i--){
		if(w[i]){
			ji=(ji+p3[i]%p*p2[t++]%p)%p;  // 奇数个数+=3^i * 2^k 
		}
	}
	ans=(total-ji)%p;		//计算偶数个数 
	while(ans<0) ans+=p;	//处理负数情况 
	printf("%lld",ans);
}
2022/7/29 20:52
加载中...