結果

問題 No.2330 Eat Slime
ユーザー Naoto FujiwaraNaoto Fujiwara
提出日時 2023-05-30 18:40:10
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 3,934 bytes
コンパイル時間 1,008 ms
コンパイル使用メモリ 90,544 KB
実行使用メモリ 60,584 KB
最終ジャッジ日時 2023-08-28 00:55:40
合計ジャッジ時間 35,164 ms
ジャッジサーバーID
(参考情報)
judge15 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,380 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 1 ms
4,376 KB
testcase_03 AC 1 ms
4,380 KB
testcase_04 AC 1 ms
4,380 KB
testcase_05 WA -
testcase_06 WA -
testcase_07 AC 1,477 ms
54,076 KB
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 AC 136 ms
8,496 KB
testcase_12 AC 1,465 ms
52,932 KB
testcase_13 AC 1,431 ms
53,120 KB
testcase_14 AC 263 ms
13,696 KB
testcase_15 AC 765 ms
35,476 KB
testcase_16 AC 1,427 ms
50,924 KB
testcase_17 WA -
testcase_18 AC 1,540 ms
60,200 KB
testcase_19 WA -
testcase_20 AC 1,534 ms
60,196 KB
testcase_21 WA -
testcase_22 AC 1,539 ms
60,264 KB
testcase_23 AC 1,536 ms
60,204 KB
testcase_24 AC 1,536 ms
60,208 KB
testcase_25 AC 1,534 ms
60,200 KB
testcase_26 AC 1,532 ms
60,184 KB
testcase_27 AC 1,539 ms
60,464 KB
testcase_28 AC 1,532 ms
60,316 KB
testcase_29 AC 1,551 ms
60,204 KB
testcase_30 AC 1,542 ms
60,316 KB
testcase_31 AC 1,537 ms
60,308 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<iostream>
#include<set>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>
#include<numeric>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
const ll INF=1LL<<60;
typedef pair<int,int> P;
typedef pair<int,P> PP;
const ll MOD=998244353;


class NTT{

    private:
        ll MOD;
        const ll root=3;
        ll add(const ll x, const ll y)
        {
            return (x + y < MOD) ? x + y : x + y - MOD;
        }
        
        ll sub(const ll x, const ll y)
        {
            return (x >= y) ? (x - y) : (MOD - y + x);
        }
        
        ll mul(const ll x, const ll y)
        {
            return x * y % MOD;
        }
        
        ll mod_pow(ll x, ll n)
        {
            ll res = 1;
            while(n > 0){
                if(n & 1){ res = mul(res, x); }
                x = mul(x, x);
                n >>= 1;
            }
            return res;
        }
        ll inverse(const ll x)
        {
            return mod_pow(x, MOD - 2);
        }


        void ntt(vector<ll>& a, const bool rev = false){

                unsigned int i, j, k, l, p, q, r, s;
                const unsigned int size = a.size();
                if(size == 1) return;
                vector<ll> b(size);
                r = rev ? (MOD - 1 - (MOD - 1) / size) : (MOD - 1) / size;
                s = mod_pow(root, r);
                vector<ll> kp(size / 2 + 1, 1);
                for(i = 0; i < size / 2; ++i) kp[i + 1] = mul(kp[i], s);
                for(i = 1, l = size / 2; i < size; i <<= 1, l >>= 1){
                    for(j = 0, r = 0; j < l; ++j, r += i){
                        for(k = 0, s = kp[i * j]; k < i; ++k){
                            p = a[k + r], q = a[k + r + size / 2];
                            b[k + 2 * r] = add(p, q);
                            b[k + 2 * r + i] = mul(sub(p, q), s);
                        }
                    }
                    swap(a, b);
                }
                if(rev){
                    s = inverse(size);
                    for(i = 0; i < size; i++){ a[i] = mul(a[i], s); }
                }
            }

    public:
        NTT(ll mod=998244353):MOD(mod){}; 

        //
        //vector<ll> c = ntt(a,b)みたいにして使う
        vector<ll> operator()(const vector<ll>& a, const vector<ll>& b){
            const int size = (int)a.size() + (int)b.size() - 1;
            ll t = 1;
            while(t < size){ t <<= 1; }

            vector<ll> A(t, 0), B(t, 0);
            
            for(int i = 0; i < (int)a.size(); i++){ A[i] = a[i]; }
            for(int i = 0; i < (int)b.size(); i++){ B[i] = b[i]; }
            
            ntt(A), ntt(B);
            for (int i = 0; i < t; i++){ A[i] = mul(A[i], B[i]); }
            ntt(A, true);
            A.resize(size);
            
            return A;
        }
};



int main(){
    ll N,M,X;
    cin>>N>>M>>X;
    vector<ll> input(N);
    vector<vector<ll>> C(6,vector<ll>(N,0));
    for(int i=0;i<N;i++){
        cin>>input[i];
        C[input[i]][i]=1;
    }

    vector<ll> A(M),B(M),Y(M);
    for(int j=0;j<M;j++){
        cin>>A[j]>>B[j]>>Y[j];
        A[j]--;//0-indexにしておく
    }

    vector<vector<ll>> points(6,vector<ll>(N,0));
    for(int j=0;j<M;j++){
        //色B[j] のスライムで 左からA[j]番目にある得点はY[j]
        points[B[j]][A[j]]+=Y[j];
    }

    vector<vector<ll>> res(6);//色iについての畳み込み結果がp[i]

    NTT ntt;
    for(int j=1;j<=5;j++){//各々の色について
        reverse(points[j].begin(),points[j].end());
        res[j]=ntt(points[j],C[j]);
    }

    ll sz=2*N-1;
    ll ans=0;
    for(int i=N-1;i<=res[1].size()-1;i++){
        ll cand=0;
        for(int j=1;j<=5;j++){//各々の色についてj=1,2,3,4,5
            cand+=res[j][i];
        }
        ans=max(ans,cand+X*(i-(N-1)));
    }
    cout<<ans<<endl;






}
0