結果
| 問題 |
No.435 占い(Extra)
|
| コンテスト | |
| ユーザー |
koyumeishi
|
| 提出日時 | 2016-04-19 05:04:02 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 6,253 bytes |
| コンパイル時間 | 1,473 ms |
| コンパイル使用メモリ | 122,692 KB |
| 実行使用メモリ | 42,880 KB |
| 最終ジャッジ日時 | 2024-10-08 11:17:26 |
| 合計ジャッジ時間 | 4,462 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | WA * 4 |
| other | WA * 32 |
ソースコード
#include <iostream>
#include <vector>
#include <cstdio>
#include <sstream>
#include <map>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>
#include <functional>
#include <set>
#include <ctime>
#include <random>
#include <chrono>
#include <cassert>
using namespace std;
namespace {
using Integer = long long; //__int128;
template<class T> istream& operator >> (istream& is, vector<T>& vec){for(T& val: vec) is >> val; return is;}
template<class T> istream& operator , (istream& is, T& val){ return is >> val;}
template<class T> ostream& operator << (ostream& os, const vector<T>& vec){for(int i=0; i<vec.size(); i++) os << vec[i] << (i==vec.size()-1?"":" "); return os;}
template<class T> ostream& operator , (ostream& os, const T& val){ return os << " " << val;}
template<class H> void print(const H& head){ cout << head; }
template<class H, class ... T> void print(const H& head, const T& ... tail){ cout << head << " "; print(tail...); }
template<class ... T> void println(const T& ... values){ print(values...); cout << endl; }
template<class H> void eprint(const H& head){ cerr << head; }
template<class H, class ... T> void eprint(const H& head, const T& ... tail){ cerr << head << " "; print(tail...); }
template<class ... T> void eprintln(const T& ... values){ print(values...); cerr << endl; }
string operator "" _s (const char* str, size_t size){ return move(string(str)); }
constexpr Integer my_pow(Integer x, Integer k, Integer z=1){return k==0 ? z : k==1 ? z*x : (k&1) ? my_pow(x*x,k>>1,z*x) : my_pow(x*x,k>>1,z);}
constexpr Integer my_pow_mod(Integer x, Integer k, Integer M, Integer z=1){return k==0 ? z%M : k==1 ? z*x%M : (k&1) ? my_pow_mod(x*x%M,k>>1,M,z*x%M) : my_pow_mod(x*x%M,k>>1,M,z);}
constexpr unsigned long long operator "" _ten (unsigned long long value){ return my_pow(10,value); }
inline int k_bit(Integer x, int k){return (x>>k)&1;} //0-indexed
mt19937 mt(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count());
template<class T> string join(const vector<T>& v, const string& sep){
stringstream ss; for(int i=0; i<v.size(); i++){ if(i>0) ss << sep; ss << v[i]; } return ss.str();
}
}
constexpr long long mod = 9_ten + 7;
#include <complex>
template<typename T = double>
class Fast_Fourier_Transform{
// return the vector of F[t] or f[x] where
// F[t] = sum of { f[x] * exp(-j * theta * t * x) } in x = 0 .. N-1 (FFT)
// f(x) = 1/N * sum of { F[t] * exp(j * theta * t * x) } in t = 0 .. N-1 (inverse FFT)
// where theta = 2*PI / N
// N == 2^k
static vector< complex<T> > do_fft(vector< complex<T> > A, bool inverse){
const T PI = atan2(1, 0) * 2.0;
const complex<T> j = complex<T>(0,1); // 0 + j*1.0 (j is the imaginary unit)
int N = A.size();
int k = 0; // N = 2^k
while(N>>k > 0) k++;
for(int bit=0; bit<N; bit++){
int rbit = 0;
for(int i=0, tmp_bit = bit; i<k-1; i++, rbit <<= 1, tmp_bit >>= 1){
rbit |= tmp_bit & 1;
}
rbit >>= 1;
if(bit < rbit){
swap(A[bit], A[rbit]);
}
}
int dist = 1;
T theta = -PI;
if(inverse) theta = -theta;
for(int level = 1; level<k; level++){
complex<T> W_n = exp(j * theta);
complex<T> W(1,0);
for(int x=0; x < (1<<level-1); x++){
for(int y=x; y+dist < N; y += (dist<<1)){
complex<T> tmp = A[ y+dist ] * W;
A[ y+dist ] = A[ y ] - tmp;
A[ y ] += tmp;
}
W *= W_n;
}
dist <<= 1;
theta *= 0.5;
}
if(inverse){
T k = 1.0/N;
for(int i=0; i<N; i++){
A[i] *= k;
}
}
return A;
}
template<typename U=T>
static void vec_resize(vector<U> &A, const U val){
int n = A.size();
int k = 1;
while(n > k) k<<=1;
A.resize(k, val);
}
public:
Fast_Fourier_Transform(){};
static vector< complex<T> > FFT(vector< complex<T> > A){
vec_resize<complex<T>>(A, complex<T>(0,0));
return do_fft(A, false);
}
static vector< complex<T> > IFFT(vector< complex<T> > A){
//vec_resize<complex<T>>(A, complex<T>(0,0));
return do_fft(A, true);
}
static vector< complex<T> > FFT(vector<T> A){
vec_resize<T>(A, 0);
vector<complex<T>> B(A.size());
for(int i=0; i<B.size(); i++){
B[i] = complex<T>(A[i], 0);
}
return do_fft(B, false);
}
static vector< complex<T> > FFT(vector<int> A){
vec_resize<int>(A, T(0));
vector<complex<T>> B(A.size());
for(int i=0; i<B.size(); i++){
B[i] = complex<T>(A[i], 0);
}
return do_fft(B, false);
}
static vector<long long> round(vector<complex<T>> &&A){
vector<long long> ret(A.size());
for(int i=0; i<A.size(); i++){
ret[i] = A[i].real() + (A[i].real()<0?-0.5:0.5);
}
return ret;
}
// vector<double> C | C[i] = ΣA[i]B[j]
static vector<complex<T>> convolution(vector<T> &A, vector<T> &B){
//reverse(B.begin(), B.end());
int n = max(A.size(), B.size());
//A.resize(n, 0);
//B.resize(n, 0);
auto A_FFT = FFT(A);
auto B_FFT = FFT(B);
for(int i=0; i<n; i++){
A_FFT[i] *= B_FFT[i];
}
return IFFT(A_FFT);
}
};
int main(){
int t;
cin >> t;
const int sz = 3000;
vector<vector<int>> nCk(sz, vector<int>(sz, 0));
nCk[0][0] = 1;
for(int i=1; i<sz; i++){
for(int j=0; j<=i; j++){
nCk[i][j] = (nCk[i-1][j] + (j>0?nCk[i-1][j-1]:0)) % 9;
}
}
vector<double> B(nCk[sz-1].begin(), nCk[sz-1].end());
B.resize(1<<18);
//reverse(B.begin(), B.end());
vector<double> A(1<<18, 0);
while(t--){
string s;
cin >> s;
bool zero = true;
for(int i=0; i<s.size(); i++){
if(s[i] != '0'){
zero = false;
break;
}
}
if(zero){
println(0);
continue;
}
while(s.size() > sz){
fill(A.begin(), A.end(), 0.0);
for(int i=0; i<s.size(); i++){
A[i] = (s[i] - '0') * 10;
}
auto res = Fast_Fourier_Transform<>::round( Fast_Fourier_Transform<>::convolution(A,B) );
string t;
for(int i=0; i<s.size()-sz+1; i++){
int val = res[i+sz-1] / 10;
val %= 9;
t += val + '0';
}
//cerr << t << endl;
swap(s,t);
}
vector<int> v(s.size());
for(int i=0; i<s.size(); i++){
v[i] = s[i] - '0';
if(v[i] == 0) v[i] = 9;
}
long long ans = 0;
int n = s.size();
for(int i=0; i<n; i++){
long long k = nCk[n-1][i];
ans += (k * v[i]);
ans %= 9;
}
if(ans == 0) ans = 9;
println(ans);
}
return 0;
}
koyumeishi