记录编号 147100 评测结果 AAAAAAAAAA
题目名称 [WC 2014]时空穿梭 最终得分 100
用户昵称 GravatarAsm.Def 是否通过 通过
代码语言 C++ 运行时间 4.651 s
提交时间 2015-01-24 13:39:17 内存使用 121.68 MiB
显示代码纯文本
/*====================Asm.Def========================*/
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <memory.h>
#include <iostream>
using namespace std;
template <typename T>inline void getd(T &x){
	char ch = getchar();bool neg = 0;
	while(!isdigit(ch) && ch != '-')ch = getchar();
	if(ch == '-')ch = getchar(), neg = 1;
	x = ch - '0';
	while(isdigit(ch = getchar()))x = x * 10 + ch - '0';
	if(neg)x = -x;
}
/*======================================================*/
typedef long long LL;
const int maxm = 100000, maxn = 11, maxc = 20;
int C[maxc+2][maxm+2], F[maxc+2][maxm+2], S[maxc+1][maxm+1][maxn+2], mod = 10007;

inline void init(){
	int i, j, c, p;
	for(i = 0;i <= maxm;++i)C[0][i] = 1;
	for(j = 1;j <= maxc;++j)for(i = 1;i <= maxm;++i)
		C[j][i] = (C[j-1][i-1] + C[j][i-1]) % mod;
	
	for(c = 2;c <= maxc;++c)for(i = 1;i <= maxm;++i){
		F[c][i] = (F[c][i] + C[c-2][i-1]) % mod;
		for(j = i<<1;j <= maxm;j += i)
			F[c][j] = (F[c][j] + mod - F[c][i]) % mod;
		p = 1;
		for(j = 0;j <= maxn;++j){
			S[c][i][j] = (S[c][i-1][j] + F[c][i] * p) % mod;
			p = p * i % mod;
		}
	}
}

inline void multi(int *poly, int &n, int a, int b){//poly * (a + bx)
	int i;
	static int tmp[maxn+2];
	for(i = 0;i <= n;++i)tmp[i+1] = poly[i] * b % mod;
	++n;poly[n] = 0;
	for(i = 0;i <= n;++i)poly[i] = (poly[i] * a + tmp[i]) % mod;
}

inline void Query(){
	static int M[maxm+2], seg[maxn*400], tmp[maxn*1000], Poly[maxn], X, n, c;
	int i, j, Ans = 0, Min = maxm + 2, t = 1, cnt = 0;
	getd(n), getd(c);
	for(i = 0;i < n;++i)getd(M[i]), Min = min(Min, M[i]), Poly[i] = 0;
	Poly[n] = 0;
	tmp[0] = 1;
	for(i = 0;i < n;++i){
		int k = max((int)sqrt(M[i]), 1), k2 = M[i] / k;
		for(j = 2;j <= k;++j)if(M[i] / j != M[i] / tmp[t-1])tmp[t++] = j;
		for(j = k2;j >= 1;--j)if(M[i] / tmp[t-1] != j)tmp[t++] = M[i] / (j+1) + 1;
	}
	sort(tmp, tmp + t);
	seg[cnt++] = 1;
	for(i = 0;i < t && tmp[i] <= Min;++i)
		if(seg[cnt-1] != tmp[i])seg[cnt++] = tmp[i];
	seg[cnt] = Min+1;
	for(i = 0;i < cnt;++i){
		if(seg[i+1]-seg[i] < n){//暴力
			for(j = seg[i];j < seg[i+1];++j){
				X = 1;
				for(int k = 0;k < n;++k){
					t = (M[k] / j) % mod;
					X = X * ((M[k] * t + mod - ((t * (t + 1))>>1)* j) % mod) % mod;
				}
				Ans = (Ans + F[c][j] * X) % mod;
			}
		}
		else{
			int p = 1;
			t = (M[0] / seg[i]) % mod;
			Poly[0] = t * M[0] % mod, Poly[1] = mod - ((t * (t+1)) >> 1) % mod;
			for(int k = 1;k < n;++k){
				t = (M[k] / seg[i]) % mod;
				multi(Poly, p, t * M[k] % mod, mod - ((t * (t+1)) >> 1) % mod);
			}
			for(int k = 0;k <= n;++k)
				Ans = (Ans + Poly[k] * (S[c][seg[i+1]-1][k] + mod - S[c][seg[i]-1][k]) % mod) % mod;
		}
	}
	printf("%d\n", Ans);
}

int main(){
	#if defined DEBUG
	freopen("test", "r", stdin);
	//freopen("output.txt", "w", stdout);
	#else
	freopen("WC2014A.in", "r", stdin);
	freopen("WC2014A.out", "w", stdout);
	#endif
	int T;getd(T);
	init();
	while(T--)
		Query();
	
	
	#if defined DEBUG
	cout << endl << (double)clock()/CLOCKS_PER_SEC << endl;
	#endif
	return 0;
}