牛客網Wannafly挑戰賽29 B - 白井黑子 亂搞

Description


kuroko 作爲常盤臺唯一的空間系能力者,在每年例行的能力測試中可絕對不能讓 misaka 失望哦,但是由於她的等級只是 level 4「大能力者」,在能力測試中會遇到不少困難。kuroko 是一個凡事都會盡力的好女孩,所以請你幫她算出她最多能完成多少測試吧

對於空間系能力者測試的內容是檢驗對物體進行空間移動的能力,測驗時一共有 n 個物品放在一條直線上,每個物品都有一個座標 ai ,kuroko 可以選擇兩個物品並使用能力交換它們的位置,但是如果兩個物品的座標不滿足 kuroko 的計算公式的話,她就沒有辦法使用能力。

具體來說,對於座標 ai ,其在 kuroko 的計算公式中是用參數 f(ai) 表示的。f(ai) 是 ai 各數位相乘的結果,由於 level 4「大能力者」在學園都市中也是很強大的存在,所以滿足公式的條件不會太苛刻,對於兩個物品 ai, aj ,如果 f(ai) x f(aj) 不能被某個自然數的 k 次冪表示 的話,那麼 kuroko 就能對這兩個物品使用能力。

現在 kuroko 想知道,有多少對物品她可以對其施展能力,知道了這個後她就知道自己能完成多少測驗了。

這裏認爲任何自然數的 0 次冪都是 1。

2 ≤ n ≤ 105, 0 ≤ ai, k ≤ 1018

Solution


我們把f分解一下,質數只有2、3、5、7四種。兩數相乘是某個自然數的k次冪說明它們指數上和模k爲0。由於260小於1018,我們開604的桶直接統計就沒了
注意k=0和k=1的情況

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <map>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)

typedef long long LL;
const int N=200005;

LL cnt[63][63][63][63],p[N][4];

LL a[N],k;

int n,tot;

void solve1() {
	LL ans=1LL*n*(n-1)/2;
	rep(i,1,n) {
		LL v,x=1; scanf("%lld",&v);
		for (;v;v/=10) x=x*(v%10);
		if (!x) continue;
		a[++tot]=x;
		for (;x%2==0;x/=2) p[tot][0]++; p[tot][0]%=k;
		for (;x%3==0;x/=3) p[tot][1]++; p[tot][1]%=k;
		for (;x%5==0;x/=5) p[tot][2]++; p[tot][2]%=k;
		for (;x%7==0;x/=7) p[tot][3]++; p[tot][3]%=k;
	}
	rep(i,tot+1,n) ans=(ans-(n-i+tot));
	n=tot;
	rep(i,1,n) {
		if ((k-p[i][0]%k)%k<=60&&(k-p[i][1]%k)%k<=60&&(k-p[i][2]%k)%k<=60&&(k-p[i][3]%k)%k<=60) {
			ans-=cnt[(k-p[i][0]%k)%k][(k-p[i][1]%k)%k][(k-p[i][2]%k)%k][(k-p[i][3]%k)%k];
		}
		cnt[p[i][0]][p[i][1]][p[i][2]][p[i][3]]++;
	}
	printf("%lld\n", ans);
}

void solve3() {
	LL ans=(n-1)*n/2,wjp=0;
	rep(i,1,n) {
		LL v,x=1; scanf("%lld",&v);
		for (;v;v/=10) x=x*(v%10);
		a[i]=x;
		if (x==1) wjp++;
		if (!x) continue;
		for (;x%2==0;x/=2) p[i][0]++;
		for (;x%3==0;x/=3) p[i][1]++;
		for (;x%5==0;x/=5) p[i][2]++;
		for (;x%7==0;x/=7) p[i][3]++;
	}
	printf("%lld\n", ans-(wjp-1)*wjp/2);
}

int main(void) {
	freopen("data.in","r",stdin);
	freopen("myp.out","w",stdout);
	scanf("%d%lld",&n,&k);
	if (k==0) solve3();
	else if (k==1) puts("0");
	else solve1();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章