結果
| 問題 |
No.3080 Colonies on Line
|
| コンテスト | |
| ユーザー |
沙耶花
|
| 提出日時 | 2025-03-28 23:01:41 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,456 ms / 6,500 ms |
| コード長 | 6,746 bytes |
| コンパイル時間 | 4,769 ms |
| コンパイル使用メモリ | 268,512 KB |
| 実行使用メモリ | 10,928 KB |
| 最終ジャッジ日時 | 2025-03-28 23:02:06 |
| 合計ジャッジ時間 | 22,667 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 35 |
ソースコード
#include <stdio.h>
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
using mint = modint998244353;
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf32 1000000000
#define Inf64 1000000000000000001LL
vector<mint> mul(vector<mint> a,vector<mint> b){
return convolution(a,b);
}
mint Bostan_Mori(vector<mint> a,vector<mint> c,long long n){
while(a.size()>=c.size())c.push_back(0);
while(n!=0){
auto cinv = c;
for(int i=1;i<cinv.size();i+=2)cinv[i] *= -1;
a = mul(a,cinv);
c = mul(c,cinv);
{
vector<mint> na;
for(int i=(n&1LL);i<a.size();i+=2)na.push_back(a[i]);
swap(a,na);
}
{
vector<mint> nc;
for(int i=0;i<c.size();i+=2)nc.push_back(c[i]);
swap(c,nc);
}
n>>=1;
}
return a[0];
}
void solve2(int N,int K){
vector dp(N,vector<mint>(2,0));
rep(i,N){
dp[i][0]++;
if(i-K-1>=0)dp[i][0] += dp[i-K-1][1];
if(i>0)dp[i][1] += dp[i-1][0] + dp[i-1][1];
if(i-K-1>=0)dp[i][1] -= dp[i-K-1][0] + dp[i-K-1][1];
rep(j,2){
if(i!=0)dp[i][j] += dp[i-1][j];
}
}
mint ans = 0;
rep(i,N){
if(i==0)continue;
ans += dp[i][1]-dp[i-1][1];;
}
ans++;
cout<<ans.val()<<endl;
}
// https://nyaannyaan.github.io/library/fps/formal-power-series.hpp
struct FormalPowerSeries : vector<mint> {
using vector<mint>::vector;
using FPS = FormalPowerSeries;
FPS &operator+=(const FPS &r) {
if (r.size() > this->size()) this->resize(r.size());
for (int i = 0; i < (int)r.size(); i++) (*this)[i] += r[i];
return *this;
}
FPS &operator+=(const mint &r) {
if (this->empty()) this->resize(1);
(*this)[0] += r;
return *this;
}
FPS &operator-=(const FPS &r) {
if (r.size() > this->size()) this->resize(r.size());
for (int i = 0; i < (int)r.size(); i++) (*this)[i] -= r[i];
return *this;
}
FPS &operator-=(const mint &r) {
if (this->empty()) this->resize(1);
(*this)[0] -= r;
return *this;
}
FPS &operator*=(const FPS &r) {
auto ret = convolution(r,*this);
return (*this) = FPS(ret.begin(),ret.end());
}
FPS &operator*=(const mint &v) {
for (int k = 0; k < (int)this->size(); k++) (*this)[k] *= v;
return *this;
}
FPS &operator/=(const FPS &r) {
if (this->size() < r.size()) {
this->clear();
return *this;
}
int n = this->size() - r.size() + 1;
if ((int)r.size() <= 64) {
FPS f(*this), g(r);
g.shrink();
mint coeff = g.back().inv();
for (auto &x : g) x *= coeff;
int deg = (int)f.size() - (int)g.size() + 1;
int gs = g.size();
FPS quo(deg);
for (int i = deg - 1; i >= 0; i--) {
quo[i] = f[i + gs - 1];
for (int j = 0; j < gs; j++) f[i + j] -= quo[i] * g[j];
}
*this = quo * coeff;
this->resize(n, mint(0));
return *this;
}
return *this = ((*this).rev().pre(n) * r.rev().inv(n)).pre(n).rev();
}
FPS &operator%=(const FPS &r) {
*this -= *this / r * r;
shrink();
return *this;
}
FPS operator+(const FPS &r) const { return FPS(*this) += r; }
FPS operator+(const mint &v) const { return FPS(*this) += v; }
FPS operator-(const FPS &r) const { return FPS(*this) -= r; }
FPS operator-(const mint &v) const { return FPS(*this) -= v; }
FPS operator*(const FPS &r) const { return FPS(*this) *= r; }
FPS operator*(const mint &v) const { return FPS(*this) *= v; }
FPS operator/(const FPS &r) const { return FPS(*this) /= r; }
FPS operator%(const FPS &r) const { return FPS(*this) %= r; }
FPS operator-() const {
FPS ret(this->size());
for (int i = 0; i < (int)this->size(); i++) ret[i] = -(*this)[i];
return ret;
}
void shrink() {
while (this->size() && this->back() == mint(0)) this->pop_back();
}
FPS rev() const {
FPS ret(*this);
reverse(ret.begin(), ret.end());
return ret;
}
FPS dot(FPS r) const {
FPS ret(min(this->size(), r.size()));
for (int i = 0; i < (int)ret.size(); i++) ret[i] = (*this)[i] * r[i];
return ret;
}
FPS pre(int sz) const {
return FPS((*this).begin(), (*this).begin() + min((int)this->size(), sz));
}
FPS operator>>(int sz) const {
if ((int)this->size() <= sz) return {};
FPS ret(*this);
ret.erase(ret.begin(), ret.begin() + sz);
return ret;
}
FPS operator<<(int sz) const {
FPS ret(*this);
ret.insert(ret.begin(), sz, mint(0));
return ret;
}
FPS diff() const {
const int n = (int)this->size();
FPS ret(max(0, n - 1));
mint one(1), coeff(1);
for (int i = 1; i < n; i++) {
ret[i - 1] = (*this)[i] * coeff;
coeff += one;
}
return ret;
}
FPS integral() const {
const int n = (int)this->size();
FPS ret(n + 1);
ret[0] = mint(0);
if (n > 0) ret[1] = mint(1);
auto mod = mint::mod();
for (int i = 2; i <= n; i++) ret[i] = (-ret[mod % i]) * (mod / i);
for (int i = 0; i < n; i++) ret[i + 1] *= (*this)[i];
return ret;
}
mint eval(mint x) const {
mint r = 0, w = 1;
for (auto &v : *this) r += w * v, w *= x;
return r;
}
FPS log(int deg = -1) const {
assert((*this)[0] == mint(1));
if (deg == -1) deg = (int)this->size();
return (this->diff() * this->inv(deg)).pre(deg - 1).integral();
}
FPS pow(int64_t k, int deg = -1) const {
const int n = (int)this->size();
if (deg == -1) deg = n;
if (k == 0) {
FPS ret(deg);
if (deg) ret[0] = 1;
return ret;
}
for (int i = 0; i < n; i++) {
if ((*this)[i] != mint(0)) {
mint rev = mint(1) / (*this)[i];
FPS ret = (((*this * rev) >> i).log(deg) * k).exp(deg);
ret *= (*this)[i].pow(k);
ret = (ret << (i * k)).pre(deg);
if ((int)ret.size() < deg) ret.resize(deg, mint(0));
return ret;
}
if (__int128_t(i + 1) * k >= deg) return FPS(deg, mint(0));
}
return FPS(deg, mint(0));
}
FPS inv(int deg = -1) const {
assert((*this)[0] != mint(0));
if (deg == -1) deg = (*this).size();
FPS ret({mint(1) / (*this)[0]});
for (int i = 1; i < deg; i <<= 1)
ret = (ret + ret - ret * ret * (*this).pre(i << 1)).pre(i << 1);
return ret.pre(deg);
}
FPS exp(int deg = -1) const{
assert((*this).size() == 0 || (*this)[0] == mint(0));
if (deg == -1) deg = (int)this->size();
FPS ret({mint(1)});
for (int i = 1; i < deg; i <<= 1) {
ret = (ret * (pre(i << 1) + mint(1) - ret.log(i << 1))).pre(i << 1);
}
return ret.pre(deg);
}
};
using fps = FormalPowerSeries;
int main(){
long long N,K;
cin>>N>>K;
/*
if(N<=500000){
solve2(N,K);
//return 0;
}
*/
fps f(K+1);
rep(i,K)f[i+1] = 1;
fps P = f;
{
fps t(2,0);
t[1] = 1;
P *= t;
}
{
fps t(2,0);
t[0] = 1;
t[1] = -1;
P *= t;
}
fps Q;
{
auto t = f;
t *= -1;
t[0]++;
Q = t;
}
{
fps t(2,0);
t[0] = 1;
t[1] = -1;
Q *= t;
}
{
fps t = f;
fps tt(K+2);
tt[K+1] ++;
t *= tt;
Q -= t;
}
{
fps t(3);
t[0] = 1;
t[1] = -2;
t[2] = 1;
Q *= t;
}
cout<<(1+Bostan_Mori(P,Q,N)).val()<<endl;
return 0;
}
沙耶花