結果

問題 No.2952 Invision of Multiples
ユーザー 蜜蜂蜜蜂
提出日時 2024-10-25 22:58:01
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 3,839 ms / 4,000 ms
コード長 4,559 bytes
コンパイル時間 4,146 ms
コンパイル使用メモリ 210,020 KB
実行使用メモリ 44,160 KB
最終ジャッジ日時 2024-10-25 23:00:13
合計ジャッジ時間 130,527 ms
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,812 KB
testcase_01 AC 2 ms
6,820 KB
testcase_02 AC 3,484 ms
43,776 KB
testcase_03 AC 71 ms
6,820 KB
testcase_04 AC 70 ms
6,820 KB
testcase_05 AC 70 ms
6,820 KB
testcase_06 AC 70 ms
6,824 KB
testcase_07 AC 70 ms
6,816 KB
testcase_08 AC 70 ms
6,816 KB
testcase_09 AC 2,231 ms
27,264 KB
testcase_10 AC 2,060 ms
25,216 KB
testcase_11 AC 3,386 ms
42,964 KB
testcase_12 AC 3,469 ms
43,592 KB
testcase_13 AC 1,962 ms
25,088 KB
testcase_14 AC 3,507 ms
42,368 KB
testcase_15 AC 3,677 ms
43,904 KB
testcase_16 AC 3,685 ms
44,032 KB
testcase_17 AC 3,833 ms
43,904 KB
testcase_18 AC 3,839 ms
44,032 KB
testcase_19 AC 3,504 ms
44,032 KB
testcase_20 AC 3,533 ms
44,160 KB
testcase_21 AC 3,536 ms
44,020 KB
testcase_22 AC 3,485 ms
44,020 KB
testcase_23 AC 3,596 ms
44,032 KB
testcase_24 AC 3,568 ms
44,016 KB
testcase_25 AC 3,584 ms
44,028 KB
testcase_26 AC 3,541 ms
44,032 KB
testcase_27 AC 3,735 ms
44,028 KB
testcase_28 AC 3,675 ms
44,156 KB
testcase_29 AC 3,706 ms
43,904 KB
testcase_30 AC 3,679 ms
44,032 KB
testcase_31 AC 3,757 ms
44,032 KB
testcase_32 AC 3,760 ms
43,904 KB
testcase_33 AC 3,497 ms
44,032 KB
testcase_34 AC 3,428 ms
44,032 KB
testcase_35 AC 3,428 ms
44,032 KB
testcase_36 AC 3,589 ms
44,028 KB
testcase_37 AC 3,594 ms
44,032 KB
testcase_38 AC 3,656 ms
43,904 KB
testcase_39 AC 3,483 ms
44,032 KB
testcase_40 AC 3,485 ms
44,028 KB
testcase_41 AC 3,433 ms
44,032 KB
testcase_42 AC 3,430 ms
43,904 KB
testcase_43 AC 3,457 ms
43,904 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

// g++-13 1.cpp -std=c++17 -O2 -I .
#include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/tag_and_trait.hpp>
using namespace __gnu_pbds;


#include <atcoder/modint>
#include <atcoder/maxflow>
#include <atcoder/math>
#include <atcoder/mincostflow>
using namespace atcoder;


using ll = long long;
using ld = long double;

using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vst = vector<string>;
using vvst = vector<vst>;
 
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define pq_big(T) priority_queue<T,vector<T>,less<T>>
#define pq_small(T) priority_queue<T,vector<T>,greater<T>>
#define all(a) a.begin(),a.end()
#define rep(i,start,end) for(ll i=start;i<(ll)(end);i++)
#define per(i,start,end) for(ll i=start;i>=(ll)(end);i--)
#define uniq(a) sort(all(a));a.erase(unique(all(a)),a.end())

random_device seed;
mt19937_64 randint(seed());

ll grr(ll mi, ll ma) { // [mi, ma)
    return mi + randint() % (ma - mi);
}

// https://judge.yosupo.jp/submission/82871
// https://judge.yosupo.jp/submission/233535

#include <vector>

template< typename S, S (*op)(S, S), S (*e)() >
struct segmenttree{
  private:
  int _n;
  std::vector<S> node;

  public:
  segmenttree() = default;
    
  segmenttree(int n){
    _n=1;
    while(_n<n)_n*=2;
    node.resize(2*_n,e());
  }
  segmenttree(std::vector<S> &v){
    int n=v.size();
    _n=1;
    while(_n<n)_n*=2;
    node.resize(2*_n,e());
    for(int i=0;i<n;i++){
      node[i+_n]=v[i];
    }
    for(int i=_n-1;i>=0;i--){
      node[i]=op(node[2*i],node[2*i+1]);
    }
  }

  // [i] <- val
  void set(int i,S val){
    i+=_n;
    node[i]=val;
    while(i>1){
      i>>=1;
      node[i]=op(node[2*i],node[2*i+1]);
    }
  }

  // [i] <- op([i],val)
  void update(int i,S val){
    i+=_n;
    node[i]=op(node[i],val);
    while(i>1){
      i>>=1;
      node[i]=op(node[2*i],node[2*i+1]);
    }
  }

  S get(int i){
    i+=_n;
    return node[i];
  }

  S prod(int l,int r){
    S pdl=e(),pdr=e();
    l+=_n;r+=_n;

    while(l<r){
      if(l&1)pdl=op(pdl,node[l++]);
      if(r&1)pdr=op(node[--r],pdr);
      l>>=1;r>>=1;
    }

    return op(pdl,pdr);
  };
};


using mint = modint998244353;

mint op(mint a,mint b){
  return a+b;
}
mint e(){
  return 0;
}

int sq = 100;

mint f(int m,int x,int y){
  // ax > by かつ ax <= m なる (a, b) の個数
  // sum_a(= 0 to m / x - 1) floor((a * x + x - 1) / y)

  // 2a > 3b かつ 2a <= 7
  // 2-1/3 + 4-1/3 + 6-1/3
  mint res=floor_sum(m/x,y,x,x-1);

  // mint nv=0;
  // rep(i,1,m+1){
  //   rep(j,1,m+1){
  //     if(i*x>j*y&&i*x<=m){
  //       nv++;
  //     }
  //   }
  // }
  // if(nv!=res){
  //   cout<<m<<" "<<x<<" "<<y<<" "<<res.val()<<" "<<nv.val()<<endl;
  // }

  if(res.val()==0)return res;
  // cout<<m/x<<" "<<m/y<<endl;
  res/=(m/x);
  res/=(m/y);
  return res;
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  auto st=clock();

  int n,m;cin>>n>>m;
  vi d(n);
  rep(i,0,n)cin>>d[i];

  segmenttree<mint,op,e> seg(m+1);
  vi cnt(sq+1,0);
  vector<mint> aft(sq+1,0);
  mint ans=0;

  vector<vector<mint>> f_large_small(sq+1,vector<mint>(m+1)),f_small_large(sq+1,vector<mint>(m+1));
  // f_large_small[i][j] := f(j,i)
  // f_small_large[i][j] := f(i,j)

  rep(i,1,sq+1){
    rep(j,1,m+1){
      f_large_small[i][j]=f(m,j,i);
      f_small_large[i][j]=f(m,i,j);
    }
  }

  auto ini=clock();
  cerr<<(ld)(ini-st)/(CLOCKS_PER_SEC)<<endl;

  rep(i,0,n){
    if(d[i]>sq){
      // large large
      mint ad=1;
      ad/=(m/d[i]);
      rep(j,1,m+1){
        if(j*d[i]>m)break;
        ans+=seg.prod(j*d[i]+1,m+1)*ad;
      }
      // small large
      rep(j,1,sq+1){
        ans+=cnt[j]*f_small_large[j][d[i]];
        aft[j]+=f_large_small[j][d[i]];
      }
      rep(j,1,m+1){
        if(j*d[i]>m)break;
        seg.set(j*d[i],seg.get(j*d[i])+ad);
      }
    }
    else{
      // large small
      // cout<<ans.val()<<" -> ";
      ans+=aft[d[i]];
      // cout<<ans.val()<<endl;

      // small small
      rep(j,1,sq+1){
        // if(cnt[j]>0)cout<<j<<"  : "<<cnt[j]<<"*"<<f_small_large[j][d[i]].val()<<endl;
        ans+=cnt[j]*f_small_large[j][d[i]];
      }

      cnt[d[i]]++;
    }
  }

  rep(i,0,n){
    ans*=(m/d[i]);
  }

  cout<<ans.val()<<endl;
}

/*
D large D large
D small D large
D small D small 前計算?
D large D small
*/
0