QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#880845#8330. Count off 3juan_123WA 65ms97972kbC++145.0kb2025-02-03 21:28:112025-02-03 21:28:12

Judging History

This is the latest submission verdict.

  • [2025-02-03 21:28:12]
  • Judged
  • Verdict: WA
  • Time: 65ms
  • Memory: 97972kb
  • [2025-02-03 21:28:11]
  • Submitted

answer

/*
有一个很显然的做法是考虑 dp
显然我们只关心 base 为 1,2,3,4,5,6 时 mod 7 的余数,全部记录下来得到一个 n \times 7^6 的做法。
这个做法太劣了,这么做主要是为了避免字典序的限制
我们不妨先不考虑字典序的限制,把它当作一个六维的背包去做,发现这个多重背包的计数如果你不 NTT 疑似做不了
启发我们考虑这个 base 的性质,注意到一件事情是 base = k 和 base = 7-k 在偶数位上的值相同,在奇数位上的值相反
所以你可以对偶数的奇数依次做三维的背包然后合并,合并的时候枚举偶数的那三维,对奇数的限制是每一维有两个数不能选,对它容斥。
接下来我们考虑字典序,
更进一步的发现上面的那个东西支持我们动态的加数。
可以直接枚举一个 lcp,然后做上面的过程。
所以时间复杂度是 $O(n \times 18^3)$ 的,看上去过不了但是能过。
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1000000007;
const int N = 10000;
int pw[10005][7];
int dp[10005][7][7][7];//偶数
int f[10005][7][7][7];
int pre[10005][8][8][8];
int n;
string ss;
char s[10005];
void init(){
	for(int j =1;j<=6;j++){
		pw[0][j] = 1;
		for(int i = 1;i<=N;i++)pw[i][j] = (pw[i-1][j]*j)%7;
	}
	//偶数位第一个数必须是 1
	int pro1 = 1,pro2 = 2,pro3 = 3;
	dp[0][0][0][0] = f[0][0][0][0] = 1;
	dp[1][1][1][1] = 1;f[1][0][0][0] = 1;f[1][1][2][3] = 1;
	for(int i = 1;i<=N;i++){
		int n = i;

		pro2 = pro2*2%7,pro3 = pro3*3%7;
		for(int j = 0;j<7;j++){
			for(int k =0;k<7;k++){
				for(int l =0;l<7;l++){
					dp[i+1][j][k][l] = (dp[i+1][j][k][l]+dp[i][j][k][l])%mod;
					dp[i+1][(j+1)%7][(k+pro2)%7][(l+pro3)%7] = (dp[i+1][(j+1)%7][(k+pro2)%7][(l+pro3)%7]+dp[i][j][k][l])%mod;
				}
			}
		}
		pro2 = pro2*2%7,pro3 = pro3*3%7;
		for(int j =0;j<7;j++){
			for(int k =0;k<7;k++){
				for(int l =0;l<7;l++){
				//	if(f[i][j][k][l]){cout << i << " " << j << " " << k << " " << l << "  " << f[i][j][k][l] << endl;}
					f[i+1][j][k][l] = (f[i+1][j][k][l]+f[i][j][k][l])%mod;
					f[i+1][(j+1)%7][(k+pro2)%7][(l+pro3)%7] = (f[i+1][(j+1)%7][(k+pro2)%7][(l+pro3)%7]+f[i][j][k][l])%mod;
				}
			}
		}	
	}
	for(int i = 0;i<=N;i++){
		int n = i;
		int sum = 0;
		for(int i =0;i<7;i++)for(int j =0;j<7;j++){
			int sum1 =0,sum2 = 0,sum3 = 0;
			for(int k =0;k<7;k++){
				sum = (sum+f[n][i][j][k])%mod;
				sum1 = (sum1+f[n][k][i][j])%mod;
				sum2 = (sum2+f[n][i][k][j])%mod;
				sum3 = (sum3+f[n][i][j][k])%mod;
			}
			pre[n][7][i][j] = sum1,pre[n][i][7][j] = sum2,pre[n][i][j][7] = sum3;
		}
		for(int i =0;i<7;i++)for(int j =0;j<7;j++)for(int k = 0;k<7;k++)pre[n][i][j][k] = mod-f[n][i][j][k];
		pre[n][7][7][7] = sum;
		for(int j = 0;j<7;j++){
			int sum1 =0,sum2 =0,sum3 = 0;
			for(int k =0;k<7;k++){
				for(int l =0;l<7;l++){
					sum1 = (sum1+f[n][j][k][l])%mod;
					sum2 = (sum2+f[n][k][j][l])%mod;
					sum3 = (sum3+f[n][k][l][j])%mod;
				}
			}
			pre[n][j][7][7] = (mod-sum1);
			pre[n][7][j][7] = (mod-sum2);
			pre[n][7][7][j] = (mod-sum3);
		}
	}
}
void solve(){
	cin >> ss;n = ss.size();
	for(int i = 1;i<=n;i++)s[i] = ss[i-1];
	int sum[10];memset(sum,0,sizeof(sum));
	int ans = 0;
	for(int i = 1;i<n;i++){
		if(s[i]=='0')continue;
		int c = n-i;
		int c1 = c/2,c2 = c-c1;
//		cout << c1 << " " << c2 << endl;
		vector<int>p1[10],p2[10],p3[10];
		for(int j =0;j<7;j++){
			p1[j].push_back(7);
			p1[j].push_back((7-(j+sum[1])%7)%7);// 1
			p1[j].push_back((j+sum[6])%7);// 4
			sort(p1[j].begin(),p1[j].end());p1[j].erase(unique(p1[j].begin(),p1[j].end()),p1[j].end());
		}
		for(int k =0;k<7;k++){
			p2[k].push_back(7);
			p2[k].push_back((7-(k+sum[2])%7)%7);
			p2[k].push_back((k+sum[5])%7);
			sort(p2[k].begin(),p2[k].end());p2[k].erase(unique(p2[k].begin(),p2[k].end()),p2[k].end());
		}
		for(int l =0;l<7;l++){
			p3[l].push_back(7);
			p3[l].push_back((7-(l+sum[3])%7)%7);
			p3[l].push_back((l+sum[4])%7);
			sort(p3[l].begin(),p3[l].end());p3[l].erase(unique(p3[l].begin(),p3[l].end()),p3[l].end());
		}
		for(int j =0;j<7;j++){
			for(int k = 0;k<7;k++){
				for(int l = 0;l<7;l++){
					int v1 = dp[c2][j][k][l];
					if(!v1)continue;
					int tot = 0;
					for(auto x:p1[j]){
						for(auto y:p2[k]){
							for(auto z:p3[l]){
								tot += pre[c1][x][y][z];
							}
						}
					}
					tot %= mod;
					ans = (ans+v1*tot)%mod;
				}
			}
		}
//		cout << " " << ans << endl;
//		for(int j = 1;j<=6;j++)cout << pw[c][j] << " ";cout << endl;
		for(int j = 1;j<=6;j++)sum[j] = (sum[j]+pw[c][j])%7;
	}
	if(s[n]=='1')for(int j = 1;j<=6;j++)sum[j] = (sum[j]+1)%7;
	int ok = (s[n] == '1');for(int j = 1;j<=6;j++)if(!sum[j])ok = 0;
	ans  = (ans+1)%mod;
//	cout << ok << endl;
	cout << ans << endl;
}
signed main(){
	init();
	int t;cin >> t;
	while(t--)solve();
	return 0;
}/*
1
0
0
0
1
1
1
1

1
101101001000

1
1101

1
110101

1
1000

1
1010

13

5
1
1010
110101
1000111000
101101001000


*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 65ms
memory: 97972kb

input:

5
1
1010
110101
1000111000
101101001000

output:

1
3
15
115
515

result:

wrong answer 2nd numbers differ - expected: '2', found: '3'