#define CP_BUNDLED_SOURCE #ifndef CP_BUNDLE_HEADER_3840A09F237A779E #define CP_BUNDLE_HEADER_3840A09F237A779E #ifdef TEMPLATE #else #define TEMPLATE # pragma GCC optimize("O3") #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using uint=unsigned; using ll=long long; using ull=unsigned long long; using ld=long double; using pii=pair; using pll=pair; using i128=__int128; using u128=unsigned __int128; templateusing vc=vector; templateusing vvc=vc>; templateusing vvvc=vvc>; templateusing smpq=priority_queue,greater>; templateusing bipq=priority_queue; #define rep(i,n) for(ll i=0;i<(ll)(n);i++) #define REP(i,j,n) for(ll i=(j);i<(ll)(n);i++) #define DREP(i,n,m) for(ll i=(n);i>=(m);i--) #define drep(i,n) for(ll i=((n)-1);i>=0;i--) #define rall(x) x.rbegin(),x.rend() #define mp(...) make_pair(__VA_ARGS__) #define pb push_back #define fi first #define se second #define is insert #define bg begin() #define ed end() #define all(x) x.begin(),x.end() void scan(int&a) { cin >> a; } void scan(ll&a) { cin >> a; } void scan(string&a) { cin >> a; } void scan(char&a) { cin >> a; } void scan(uint&a) { cin >> a; } void scan(ull&a) { cin >> a; } void scan(bool&a) { cin >> a; } void scan(ld&a){ cin>> a;} template void scan(vector&a) { for(auto&x:a) scan(x); } void read() {} template void read(Head&head, Tail&... tail) { scan(head); read(tail...); } #define INT(...) int __VA_ARGS__; read(__VA_ARGS__); #define LL(...) ll __VA_ARGS__; read(__VA_ARGS__); #define ULL(...) ull __VA_ARGS__; read(__VA_ARGS__); #define STR(...) string __VA_ARGS__; read(__VA_ARGS__); #define VC(type, name, ...) vector name(__VA_ARGS__); read(name); #define VVC(type, name, size, ...) vector> name(size, vector(__VA_ARGS__)); read(name); templatevoid print(T a) { cout << a; } template void print(vectora) { for(int i=0;i<(int)a.size();i++){if(i)cout<<" ";print(a[i]);}} void PRT() { cout < void PRT(T a) { print(a); cout < void PRT(Head head, Tail ... tail) { print(head); cout << " "; PRT(tail...); return; } template bool chmin(T &x, F y){ if(x>y){ x=y; return true; } return false; } template bool chmax(T &x, F y){ if(x T floor(T a,T b){ return a/b-(a%b&&((a<0)!=(b<0))); } template T ceil(T a,T b){ return a/b+(a%b&&((a<0)==(b<0))); } template T bmod(T x,T y){ return x-y*floor(x,y); } template pairdivmod(T x,T y){ T q=floor(x,y); return{q,x-q*y}; } void YesNo(bool b){ cout<<(b?"Yes":"No")<stovi(const string&s,const string&S){ vcv(s.size()); rep(i,s.size()){ auto t=S.find(s[i]); assert(t!=string::npos); v[i]=t; } return v; } template T isqrt(T x){ T F=sqrtl(x); while((F+1)*(F+1)<=x)F++; while(F*F>x)F--; return F; } template T tri(T x){return x*(x-1)/2;} //[l,r) templateT tri(T l,T r){return (r-l)*(l+r-1)/2;} //n を先頭に持ってくる template vcrot(vcv,int n){ rotate(v.begin(),v.begin()+n,v.end()); return v; } template vciota(int n){ vcv(n);rep(i,n)v[i]=i; return v; } template vcargsort(const vc&a){ auto idx=iota(a.size()); sort(all(idx),[&](int i,int j){ return (minfirst?make_pair(a[i],i)make_pair(a[j],j)); }); return idx; } template vvctrans(const vvc&a){ assert(a.size()&&a[0].size()); rep(i,a.size())assert(a[i].size()==a[0].size()); vvcb(a[0].size(),vc(a.size())); rep(i,a.size())rep(j,a[0].size())b[j][i]=a[i][j]; return b; } vctrans(const vc&a){ assert(a.size()&&a[0].size()); rep(i,a.size())assert(a[i].size()==a[0].size()); vcb(a[0].size(),string(a.size(),0)); rep(i,a.size())rep(j,a[0].size())b[j][i]=a[i][j]; return b; } template int popcount(T n){ return __builtin_popcountll(n); } template L sum(const vc&a){ return accumulate(all(a),L(0)); } template struct subset_view{ T s; struct iterator{ T s,x; bool done; T operator*()const{return x;} iterator&operator++(){ if(x==0)done=true; else x=(x-1)&s; return*this; } bool operator!=(const iterator&r)const{return done!=r.done;} }; iterator begin()const{return{s,s,false};} iterator end()const{return{s,0,true};} }; template subset_viewsubset(T s){ return{s}; } template T max(vc&a){ return *max_element(all(a)); } template T min(vc&a){ return *min_element(all(a)); } template vc presum(vc &a){ vc ret(a.size()+1); rep(i,a.size())ret[i+1]=ret[i]+a[i]; return ret; } template vc &operator+=(vc &a,F b){ for (auto&v:a)v += b; return a; } template vc &operator-=(vc&a,F b){ for (auto&v:a)v-=b; return a; } template vc &operator*=(vc&a,F b){ for (auto&v:a)v*=b; return a; } template constexpr T pow(T a,T b){ T res=1; while(b){ if(b&1)res*=a; a*=a; b/=2; } return res; } constexpr ll ten(ll a){ return pow(10,a); } templateconstexpr T inf=numeric_limits::max()/2-1; template int tbit(T x){ using U=make_unsigned_t; U y=(U)x; return y?(int)bit_width(y)-1:-1; } template int lbit(T x){ using U=make_unsigned_t; U y=(U)x; return y?(int)countr_zero(y):-1; } template int tbit(T x,int p){ using U=make_unsigned_t; constexpr int W=numeric_limits::digits; U y=(U)x; if(p<0)return -1; if(p>=W-1)return tbit(y); return tbit(y&((U(1)<<(p+1))-1)); } template int lbit(T x,int p){ using U=make_unsigned_t; constexpr int W=numeric_limits::digits; U y=(U)x; if(p<0)return lbit(y); if(p>=W)return -1; return lbit(y&(~U(0)<>(istream&is,i128&x){ string s;is>>s; x=0; int i=0,neg=0; if(s[0]=='-')neg=1,i=1; for(;i<(int)s.size();i++)x=x*10+s[i]-'0'; if(neg)x=-x; return is; } ostream& operator<<(ostream&os,i128 x){ if(x==0)return os<<0; if(x<0)os<<"-"; u128 y=x<0?-(u128)x:(u128)x; string s; while(y)s.pb('0'+y%10),y/=10; reverse(all(s)); return os<sync_with_stdio(0); #ifdef LOCAL cout< #endif #endif #endif //ax+by=c //res.fi.fi*t+res.fi.se, res.se.fi*t+res.se.se という解集合 #ifndef CP_BUNDLE_HEADER_43928B84ADA57EB6 #define CP_BUNDLE_HEADER_43928B84ADA57EB6 template struct range_set{ T covered; using P=pair; using It=typename set

::iterator; set

st; range_set():covered(0){} //[l,r) を insert void insert(T l,T r){ assert(l<=r); if(l==r)return; erase(l,r); { auto it=st.lower_bound({l,-inf}); if(it!=st.begin()&&prev(it)->second==l){ l=prev(it)->first; erase(prev(it)->first,prev(it)->second); } } { auto it=st.lower_bound({r,-inf}); if(it!=st.end()&&it->first==r){ r=it->second; erase(it->first,it->second); } } st.insert({l,r});covered+=r-l; } //[l,r) に含まれる区間を削除 //はみ出るやつは残しておく void erase(T l,T r){ assert(l<=r); if(l==r)return; rep(_,1){ auto it=st.upper_bound({l,-inf}); if(it==st.begin())break; it=prev(it); if(it->second<=l)break; covered-=min(r,it->second)-l; T tif=it->first,tis=it->second; st.erase(it); if(tif!=l)st.insert({tif,l}); if(tis>r)st.insert({r,tis}); } while(1){ auto it=st.lower_bound({l,-inf}); if(it==st.end()||it->first>=r)break; if(it->second>=r){ covered-=r-it->first; T tis=it->second;st.erase(it); if(tis!=r)st.insert({r,tis}); break; } covered-=it->second-it->first; st.erase(it); } } //x を含む区間 It find(T x){ auto it=st.upper_bound({x,inf}); if(it==st.begin())return st.end(); if(prev(it)->second<=x)return st.end(); return prev(it); } //x が含まれるか bool contains(T x){ return find(x)!=st.end(); } //[l,r) が全て含まれるか bool contains(T l,T r){ assert(l<=r); if(l==r)return true; auto it=find(l); return it!=st.end()&&r<=it->second; } //x を含む区間、なければ x より後の最初の区間 It lower_bound(T x){ auto it=st.lower_bound({x,-inf}); if(it!=st.begin()&&prev(it)->second>x)return prev(it); return it; } //[l,r) と交わる部分を列挙 vc

enumerate(T l,T r){ assert(l<=r); vc

res; for(auto it=lower_bound(l);it!=st.end()&&it->firstfirst),b=min(r,it->second); if(a struct range_set_info{ using value_type=typename info_type::value_type; struct Node{ T l,r; value_type val; }; struct cmp{ bool operator()(const Node&a,const Node&b)const{ return a.l::iterator; using CIt=typename set::const_iterator; setst; It lower_bound(T x){ auto it=st.lower_bound({x,x,info_type::e()}); if(it!=st.begin()&&prev(it)->r>x)return prev(it); return it; } CIt lower_bound(T x)const{ auto it=st.lower_bound({x,x,info_type::e()}); if(it!=st.begin()&&prev(it)->r>x)return prev(it); return it; } void add(vector&v,T l,T r,const value_type&val){ if(lv; auto it=lower_bound(l); T cur=l; while(it!=st.end()&&it->l> get(T l,T r)const{ assert(l<=r); vector>res; if(l==r)return res; auto add=[&](T a,T b,const value_type&val){ if(a==b)return; if(!res.empty()&&std::get<2>(res.back())==val)std::get<1>(res.back())=b; else res.emplace_back(a,b,val); }; T cur=l; for(auto it=lower_bound(l);it!=st.end()&&it->ll)add(cur,min(r,it->l),info_type::e()); T a=max(cur,it->l),b=min(r,it->r); add(a,b,it->val); cur=max(cur,b); } add(cur,r,info_type::e()); return res; } void clear(){st.clear();} }; #endif #ifndef CP_BUNDLE_HEADER_084E7F455B05C243 #define CP_BUNDLE_HEADER_084E7F455B05C243 #ifndef CP_BUNDLE_HEADER_AD5407378ADD496E #define CP_BUNDLE_HEADER_AD5407378ADD496E #ifndef CP_BUNDLE_HEADER_479ABBBFBD96A77B #define CP_BUNDLE_HEADER_479ABBBFBD96A77B struct barrett{ using u64=uint64_t; using u32=uint32_t; using i128=__int128_t; u64 m; int mod; void set(int mod_){ assert(mod_>0); mod=mod_; m=(i128(1)<<64)/mod; } unsigned reduce(uint64_t x){ assert(mod>0); x-=(((i128)x*m)>>64)*mod; return x struct dynamic_modint{ using u32=uint32_t; using u64=uint64_t; u32 val; dynamic_modint():val(0){} dynamic_modint(ll x){ ll v=x%get_mod(); if(v<0)v+=get_mod(); val=v; } static dynamic_modint raw(int v){ assert(v>=0); dynamic_modint mi; mi.val=v; return mi; } dynamic_modint &operator+=(const dynamic_modint&m){ u32 md=get_mod(); u32 x=val+m.val-md; val=x+(md&-(x>>31)); return *this; } dynamic_modint &operator-=(const dynamic_modint&m){ u32 md=get_mod(); u32 x=val-m.val; val=x+(md&-(x>>31)); return *this; } dynamic_modint &operator*=(const dynamic_modint&m){ val=rem(u64(val)*m.val); return *this; } dynamic_modint &operator/=(const dynamic_modint&m){ val=rem(u64(val)*m.inv().val); return *this; } dynamic_modint operator-() const{ return dynamic_modint(val?get_mod()-val:0); } dynamic_modint operator+() const { return *this; } friend dynamic_modint operator+(dynamic_modint lhs, const dynamic_modint& rhs){ return lhs+=rhs; } friend dynamic_modint operator-(dynamic_modint lhs, const dynamic_modint& rhs){ return lhs-=rhs; } friend dynamic_modint operator*(dynamic_modint lhs, const dynamic_modint& rhs){ return lhs*=rhs; } friend dynamic_modint operator/(dynamic_modint lhs,const dynamic_modint&rhs){ return lhs/=rhs; } bool operator==(const dynamic_modint&p) const{ return p.val==val; } bool operator!=(const dynamic_modint&p) const{ return p.val!=val; } dynamic_modint pow(int64_t n) const{ dynamic_modint res(1),mul(val); while(n){ if(n%2)res*=mul; mul*=mul; n/=2; } return res; } friend ostream&operator<<(ostream&os,const dynamic_modint&p){ os<>(istream&is,dynamic_modint&p){ int64_t x; is>>x; p=dynamic_modint(x); return is; } dynamic_modint inv()const{ int64_t a=val,b=get_mod(),u=1,v=0,t; #ifdef LOCAL assert(gcd(a,b)==1); #endif while(b>0){ t=a/b; swap(a-=t*b,b); swap(u-=t*v,v); } return dynamic_modint(u); } inline static u32 rem(u64 x){return barrett_reduction().reduce(x);} static inline int &get_mod(){ static int mod=0; return mod; } static void set_mod(int md){ assert(0 T extgcd(T a, T b, T &x, T &y) { T d = a; if(b != 0) { d = extgcd(b, a % b, y, x); y -= (a / b) * x; } else { x = 1; y = 0; } return d; } template pair inv(T x,T m){ T a1,a2; T res=extgcd(x,m,a1,a2); T md=m/res; a1=(a1%md+md)%md; return {a1,md}; } template pair mod_solve(T a,T b,T m){//return x s.t. ax=b mod m a%=m,b%=m;if(a<0)a+=m;if(b<0)b+=m; T g=gcd(gcd(a,b),m); a/=g,b/=g,m/=g; if(gcd(a,m)>1)return {-1,-1}; return {(inv(a,m).first*b)%m,inv(a,m).second}; } //x^2 ≡ b (mod p) ll mod_sqrt(ll b,ll p){ static mt19937 mt(random_device{}()); b%=p;if(b<0)b+=p; if(b==0)return 0; if(p==2){ return b; } assert(p>=3); using mint=dynamic_modint<20260801>;mint::set_mod(p); if(mint(b).pow((p-1)/2)==-1){ return -1; } if(p%4==3){ return mint(b).pow((p+1)/4).val; } ll t=[&](){ ll w; while(1){ ll t=mt()%p; w=t*t-b; if(mint(w).pow((p-1)/2)==mint(-1)){ return t; } } assert(0); }(); mint w=mint(t*t-b); using T=pair; auto ml=[&](T a,T b)->T{ return T{a.first*b.first+a.second*b.second*w,a.second*b.first+a.first*b.second}; }; ll e=(p+1)/2; T ans={1,0}; T gy={t,1}; while(e){ if(e%2)ans=ml(ans,gy); gy=ml(gy,gy); e/=2; } return ans.first.val; } #endif template pair,pair>extgcdasexp(T a,T b,T c){ T g=gcd(a,b); assert(a||b); if(c%g)return {{-inf,-inf},{-inf,-inf}}; c/=g,a/=g,b/=g; T x,y; extgcd(a,b,x,y); x*=c,y*=c; return {{-b,x},{a,y}}; } //at+b \in [l,r] なる t の閉区間 template pairvalidsegment(T a,T b,T l,T r){ if(a==0){ if(l<=b&&b<=r)return {-inf,inf}; return {0,-1}; } if(a>0){ return {ceil(l-b,a),floor(r-b,a)}; }else{ return {ceil(r-b,a),floor(l-b,a)}; } } void solve(){ LL(n); range_setans; ll in=isqrt(n); for(ll x=1;x<=in;x++){ auto[ab,b]=extgcdasexp(x,1,n); ll L=-inf,R=inf; //b>=1 auto seg=validsegment(b.fi,b.se,1,2e10); chmax(L,seg.fi),chmin(R,seg.se); dbg(x,L,R); dbg(ab,b); //a>=1 ll ac=ab.fi-b.fi; ll db=b.se-ab.se; dbg(ac,db); if(ac>0){ chmax(L,ceil(db+1,ac)); }else{ chmin(R,floor(db+1,ac)); } if(L>R)continue; dbg(L,R); ll sl=ab.fi*L+ab.se; ll sr=ab.fi*R+ab.se; if(sl>sr)swap(sl,sr); dbg(x,sl,sr+1); ans.insert(sl,sr+1); } for(ll ab=1;ab<=in;ab++){ auto [x,b]=extgcdasexp(ab,1,n); ll L=-inf,R=inf; //x>=1 auto seg=validsegment(x.fi,x.se,1,2e10); chmax(L,seg.fi),chmin(R,seg.se); //1<=b(b.fi,b.se,1,ab-1); chmax(L,seg2.fi),chmin(R,seg2.se); if(L<=R){ ans.insert(ab,ab+1); } } PRT(ans.covered); } signed main(){ int t=1; // cin >> t; while(t--)solve(); }