結果
問題 |
No.1276 3枚のカード
|
ユーザー |
![]() |
提出日時 | 2020-09-17 22:55:09 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 347 ms / 2,000 ms |
コード長 | 3,090 bytes |
コンパイル時間 | 1,762 ms |
コンパイル使用メモリ | 168,960 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-06-22 07:15:36 |
合計ジャッジ時間 | 13,504 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 61 |
ソースコード
#include <bits/stdc++.h> using namespace std; #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define rep2(i, s, n) for (int i = s; i < (int)(n); i++) typedef long long ll; template <ll mod> struct Fp{ ll x; constexpr Fp(ll x=0) noexcept : x ((x%mod+mod)%mod){} /*-------ここから演算子-------*/ constexpr Fp operator-() const noexcept{ return Fp(-x); } constexpr Fp& operator+=(const Fp &a) noexcept{ if((x+=a.x)>=mod)x-=mod; return *this; } constexpr Fp& operator-=(const Fp &a) noexcept{ if((x+=mod-a.x)>=mod)x-=mod; return *this; } constexpr Fp& operator*=(const Fp &a) noexcept{ (x*=a.x)%=mod; return *this; } constexpr Fp& operator/=(const Fp &a) noexcept{ return (*this)*=a.inv(); } constexpr Fp operator+(const Fp &a)const noexcept{ Fp res(*this); return res+=a; } constexpr Fp operator-(const Fp &a)const noexcept{ Fp res(*this); return res-=a; } constexpr Fp operator*(const Fp &a)const noexcept{ Fp res(*this); return res*=a; } constexpr Fp operator/(const Fp &a)const noexcept{ Fp res(*this); return res/=a; } /*-------ここまで演算子-------*/ constexpr Fp inv()const noexcept{ return (Fp)forinv((*this).x,mod).first; } friend ostream& operator<<(ostream &os,const Fp &m)noexcept{ os << m.x; return os; } friend istream& operator>>(istream &is,Fp &m)noexcept{ is >> m.x; m.x%=mod; if(m.x<0)m.x+=mod; return is; } private: //Euclidの互除法 constexpr pair<ll,ll> forinv(ll a,ll b)const noexcept{ if(b==0)return pair<ll,ll>(1,0); pair<ll,ll> ans = forinv(b,a%b); pair<ll,ll> t=pair<ll,ll>(ans.second,ans.first-a/b*ans.second); return t; } }; const ll mod=1000000007LL; using mint=Fp<mod>; ll undersqrt(ll a){//[sqrt(a)]を返す ll under=-1; ll over=a+1; while(over-under>1){ ll mid=(under+over)/2; if(mid*mid<=a)under=mid; else over=mid; } return under; } mint solve(ll a){ mint ans=0; ll tmp=undersqrt(a); for(ll i=1;i<=tmp;i++)ans+=a/i; return ans*2-tmp*tmp; } int main(){ ll N;cin >> N; ll tmp = undersqrt(N); //ansはa|b,b|c型(a=2,b=4,c=12など) mint ans=0; for(int i=1;i<=tmp;i++){ ans += solve(N/i); ans += solve(i) * ((N/i) - (N/(i+1))); } if(tmp * (tmp+1) > N){ ans -= solve(tmp); } ans += -solve(N)*2 + N; mint count=0; for(int i=1;i<=tmp;i++){ count += (mint)(N/i - 1)*(N/i - 2) + (i-1)*(i-2) * (N/i - N/(i+1)); } if(tmp*(tmp+1)>N){ count -= (tmp-1)*(tmp-2); } count -= ans*2; mint count2=0; for(int i=1;i<=tmp;i++)count2 += (N - 2)*(N/i - 1) + (N-2) * (i-1) * (N/i - N/(i+1)); if(tmp*(tmp+1)>N)count2 -= (N-2) * (tmp-1); mint sum = count2 - ans*3 - count; cout << sum << endl; assert(3LL<=N&&N<=2000000000LL); }