結果

問題 No.1661 Sum is Prime (Hard Version)
ユーザー shun2741shun2741
提出日時 2021-08-28 00:40:27
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 922 ms / 3,000 ms
コード長 3,471 bytes
コンパイル時間 4,346 ms
コンパイル使用メモリ 267,548 KB
実行使用メモリ 6,948 KB
最終ジャッジ日時 2024-05-01 05:34:39
合計ジャッジ時間 13,128 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 26 ms
6,816 KB
testcase_01 AC 25 ms
6,940 KB
testcase_02 AC 613 ms
6,940 KB
testcase_03 AC 26 ms
6,944 KB
testcase_04 AC 26 ms
6,944 KB
testcase_05 AC 25 ms
6,940 KB
testcase_06 AC 26 ms
6,944 KB
testcase_07 AC 26 ms
6,944 KB
testcase_08 AC 26 ms
6,948 KB
testcase_09 AC 26 ms
6,944 KB
testcase_10 AC 26 ms
6,940 KB
testcase_11 AC 25 ms
6,944 KB
testcase_12 AC 552 ms
6,944 KB
testcase_13 AC 534 ms
6,940 KB
testcase_14 AC 608 ms
6,940 KB
testcase_15 AC 754 ms
6,940 KB
testcase_16 AC 628 ms
6,944 KB
testcase_17 AC 589 ms
6,944 KB
testcase_18 AC 266 ms
6,944 KB
testcase_19 AC 463 ms
6,944 KB
testcase_20 AC 295 ms
6,940 KB
testcase_21 AC 478 ms
6,944 KB
testcase_22 AC 922 ms
6,940 KB
testcase_23 AC 894 ms
6,944 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;

// デバッグ表示
#define dump(x) cout << #x << ":" << (x) << endl;

// 型定義
typedef long long ll;
typedef pair<ll, ll> P;

// forループ
#define REP(i,n) for(ll i=0; i<(ll)(n); ++i)

// 定数宣言
const int INF = 1e9;
const int MOD = 1e9+7;
const ll LINF = 1e18;

// modint
using mint = modint1000000007;
// using mint = modint998244353;

// グラフ表現
using Graph = vector<vector<int>>;

// グラフの辺表現
using Edge = map<pair<int,int>,int>;

// n次元配列の初期化。第2引数の型のサイズごとに初期化していく。
template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}

// コンビネーションを計算する関数
ll pow(ll N, ll k) {
    ll res = 1;
    for (ll i = 0; i < k; ++i) res *= N;
    return res;
}

// 最大公約数
ll gcd(ll a,ll b){
   if (a%b == 0) return(b);
   else return(gcd(b, a%b));
}

// 最小公倍数
ll lcm(ll a, ll b){
    return a/gcd(a, b) * b;
}

//template
#define rrep(i,a,b) for(int i=(a);i>(b);i--)
#define ALL(v) (v).begin(),(v).end()
template<class T> inline bool chmax(T& a,T b){ if(a<b){a=b;return 1;}return 0; }
template<class T> inline bool chmin(T& a,T b){ if(a>b){a=b;return 1;}return 0; }
//end

struct BIT{
   int n; vector<int> val;
   BIT(int _n):n(_n),val(_n+1,0){}
   void add(int i,int x){for(i++;i<=n;i+=i&-i)val[i]+=x;}
   int sum(int i){int res=0; for(i++;i;i-=i&-i)res+=val[i]; return res;}
};

constexpr int R=1010101;
constexpr int C=10101;
bitset<R> isp; vector<int> ps,cs;

void init(int c){
   ps.clear(); cs.clear(); isp[0]=isp[1]=1;
   for(int p=2;p*p<=R;p++)if(!isp[p]){
      for(int q=p*p;q<=R;q+=p)isp[q]=1;
   }
   for(int i=2;i<R+1;++i)if(!isp[i]){
      ps.push_back(i);
      if(i<=c)cs.push_back(i);
   }
}

ll phi(ll x,ll a,ll cnt){
   ll res=0;
   vector<int> mu(a+1,1),minp(a+1,a);
   for(int i=1;i<a+1;++i){
      if(!isp[i]){
         for(ll j=i;j<=a;j+=i){mu[j]*=-1; chmin(minp[j],i);}
         for(ll j=i*i,k=j;k<=a;k+=j)mu[k]=0;
      } res+=mu[i]*(x/i);
   }
   vector<ll> sum(cnt,0);
   for(ll lo=1;lo<x/a;lo+=a){
      ll hi=min(lo+a,x/a);
      BIT bit(a); bitset<C> is_one;
      for(int b=0;b<cnt;++b){
         int p=cs[b],mi=max(x/p/hi,a/p),ma=min(x/p/lo,a);
         if(p<ma){
            rrep(m,ma,mi)if(mu[m]!=0 and minp[m]>p){
               res-=mu[m]*(sum[b]+x/p/m-lo+1-bit.sum(x/p/m-lo));
            }
         } sum[b]+=a-bit.sum(a-1);
         for(int q=(p-lo%p)%p;q<a;q+=p)if(!is_one[q]){
            bit.add(q,1); is_one[q]=1;
         }
      }
   } return res;
}

ll pi(ll x){
   int r=sqrt(x),c=cbrt(x); init(c);
   if(x<=R)return upper_bound(ALL(ps),x)-ps.begin();
   ll a=upper_bound(ALL(ps),c)-ps.begin(),b=upper_bound(ALL(ps),r)-ps.begin();
   ll res=phi(x,c,a)+(b+a-2)*(b-a+1)/2; int idx=b-1;
   for(int s=r;s<=x and idx>=a;s+=c){
     vector<ll> cur(c+1,0); bitset<C> val; cur[0]=b; for(int i=0;i<C;++i)val[i]=1;
      for(int p:cs)for(int q=(p-s%p)%p;q<=c;q+=p)val[q]=0;
      for(int i=1;i<c+1;++i) cur[i]=cur[i-1]+val[i];
      b=cur[c];
      while(s<=x/ps[idx] and x/ps[idx]<s+c and idx>=a){res-=cur[x/ps[idx]-s]; idx--;}
   } return res;
}

int main()
{
   cout << fixed << setprecision(15);
   ll L, R;
   cin >> L >> R;

   ll ans = pi(R) - pi(L-1) + pi(2*R-1) - pi(2*L);
    
   cout << max(0LL, ans) << endl;
   return 0;
}
0