結果
| 問題 |
No.1661 Sum is Prime (Hard Version)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-08-28 00:40:27 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 924 ms / 3,000 ms |
| コード長 | 3,471 bytes |
| コンパイル時間 | 4,465 ms |
| コンパイル使用メモリ | 257,192 KB |
| 最終ジャッジ日時 | 2025-01-24 03:47:51 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 22 |
ソースコード
#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;
}