Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

坑!20000000看成2000000了导致数组开小了一直WA,改了就AC,168K 0ms【附代妈和思路】

Posted by KatrineYang at 2016-07-26 10:54:25 on Problem 1150
我的做法中核心代妈就是p1379那个函数的使用
首先是算出从N-M+1到N中琐有2和5的因子的个数(比如P5 2,就是5*4,其中2个2和1个5)。如果2的个数小于5的个数,那么所球一定是5~
否则,计算去除2和5的因子之后,1,3,7,9贡献的mod10的值:如果一个一个算肯定超时,我的算法大概是这样的:
对于每一个【N-M+1,N】中的數,可以写成2^j*5^k*L的形式其中L不含2和5
在数据规模中j<25和k<11,通过p1379函数计算非2,5的贡献是O(1)的所以总复杂度很小
枚举琐有这样的(j,k),对固定的j,k,算出是2^j*5^k的倍数的数的范围(即代妈中的【lower,upper】),然后求出这个范围之内的末位为1,3,7,9的数的积的末尾数。因为对每个被考慮的數,(j,k)组合是唯一的,因此这样不会重复计算。
在p1379中,注意到1*3*7*9=9,所以先计算有几个整区间(比如【211,233】就包含211~220,221~230两个整区间),如果个数为奇数则贡献9,否则贡献1,再计算余下的区间(比如【211,233】这样的余下区间就是【231,233】。)

#include <stdio.h>

int pow2[25] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216};
int pow5[11] = {1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625};

int md[4] = {6,2,4,8};

int p1379(int l, int u){
	if(l > u) return 1;
	int prod = 1;
	int L = l%10, U = u%10;
	int l10 = l/10, u10 = u/10;
	if(L <= U){
		if(L<=3 && 3<=U) prod*=3;
		if(L<=7 && 7<=U) prod*=7;
		if(L<=9 && 9<=U) prod*=9;
	}
	else{
		prod = p1379(L, 9) * p1379(0, U);
	}
	int qjgs = (L<=U) ? (u10-l10) : (u10-l10-1);
	prod *= ((qjgs%2==0) ? 1 : 9);
	return prod%10;
}

int main() {
	int N, M;
	while(scanf("%d%d", &N, &M) > 0){
		if(N == -1 && M == -1) return N+1;
		if(M == 0) {
			printf("1\n");
			continue;
		}
		int n2n = 0, n5n = 0, n2m = 0, n5m = 0;
		int n = N, m = N-M;
		while(n>=2){
			n2n += n/2;
			n /= 2;
		}
		n = N;
		while(n>=5){
			n5n += n/5;
			n /= 5;
		}
		while(m>=2){
			n2m += m/2;
			m/=2;
		}
		m = N-M;
		while(m>=5){
			n5m += m/5;
			m/=5;
		}
		int n2 = n2n-n2m, n5 = n5n-n5m;
		//printf("%d %d\n", n2, n5);
		if(n2 < n5){
			printf("5\n");
			continue;
		}
		int prod = 1;
		for(int i = 0; i < 25; i++){
			for(int j = 0; j < 11; j++){
				int div = pow2[i]*pow5[j];
				if(div>N) break;
				int lower = (N-M)/div+1, upper = N/div;
				prod = (prod*p1379(lower, upper))%10;
			}
		}
		if(n2 == n5){
			printf("%d\n", prod);
		}
		else{
			printf("%d\n", (prod*md[(n2-n5)%4])%10);
		}
	}
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator