結果

問題 No.752 mod数列
ユーザー gazellegazelle
提出日時 2018-11-09 22:12:30
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 185 ms / 2,000 ms
コード長 2,684 bytes
コンパイル時間 1,305 ms
コンパイル使用メモリ 108,888 KB
最終ジャッジ日時 2025-01-06 16:02:16
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 31
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
#include<iomanip>
#include<math.h>
#include<bitset>
#include<cassert>
using namespace std;
using ll=long long;
using ld=long double;
using P=pair<ll,ll>;
#define MOD 1000000007LL
#define INF 1000000000LL
#define EPS 1e-10
#define FOR(i,n,m) for(ll i=n;i<(ll)m;i++)
#define REP(i,n) FOR(i,0,n)
#define DUMP(a) REP(d,a.size()){cout<<a[d];if(d!=a.size()-1)cout<<" ";else cout<<endl;}
#define ALL(v) v.begin(),v.end()
#define UNIQUE(v)  sort(ALL(v));v.erase(unique(ALL(v)),v.end());
#define pb push_back

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	ll p, q;
	cin >> p >> q;
	ll n = round(sqrt(p));
	vector<P> area(n + 1);
	REP(i,n + 1) {
		if(i == 0) {
			area[i].first = p + 1;
			area[i].second = INF + 10;
		} else {
			if(p % (i + 1) == 0) area[i].first = p / (i + 1) + 1;
			else area[i].first = p / (i + 1) + 1;
			area[i].second = area[i - 1].first - 1;
		}
	}
	vector<ll> area_sum(n + 1);
	REP(i,n + 1) {
		if(i == 0) {
			area_sum[i] = 0;
			continue;
		}
		ll fir = p % area[i].second;
		ll sec = p % area[i].first;
		area_sum[i] = (fir + sec) * (area[i].second - area[i].first + 1) / 2;
		if(i > 0) area_sum[i] += area_sum[i - 1];
	}
	vector<ll> els;
	for(ll i = 1; i < area[n].first; i++) {
		els.pb(p % i);
	}
	vector<ll> els_sum(els.size());
	els_sum[0] = els[0];
	FOR(i,1,els.size()) {
		els_sum[i] = els[i] + els_sum[i - 1];
	}
	vector<ll> l(q);
	vector<ll> r(q);
	REP(i,q) cin >> l[i] >> r[i];
	REP(i,q) {
		if(r[i] <= (ll)els.size()) {
			ll ans = els_sum[r[i] - 1];
			if(l[i] > 1) ans -= els_sum[l[i] - 2];
			cout << ans << endl;
			continue;
		}
		ll ans = 0;
		if(l[i] <= (ll)els.size()) {
			ans += els_sum[(ll)els.size() - 1];
			if(l[i] > 1) ans -= els_sum[l[i] - 2];
			l[i] = area[n].first;
		}
		ll l_mod = -1, r_mod = -1;
		ll lb = n, ub = -1;
		while(lb - ub > 1) {
			ll m = (lb + ub) / 2;
			if(area[m].first <= l[i]) lb = m;
			else ub = m;
		}
		l_mod = lb;
		lb = n; ub = -1;
		while(lb - ub > 1) {
			ll m = (lb + ub) / 2;
			if(area[m].first <= r[i]) lb = m;
			else ub = m;
		}
		r_mod = lb;
		if(l_mod == r_mod) {
			ll fir = p % r[i];
			ll sec = p % l[i];
			ans += (r[i] - l[i] + 1) * (fir + sec) / 2;
			cout << ans << endl;
			continue;
		}
		ll fir = p % r[i];
		ll sec = p % area[r_mod].first;
		ans += (r[i] - area[r_mod].first + 1) * (fir + sec) / 2;
		fir = p % area[l_mod].second;
		sec = p % l[i];
		ans += (area[l_mod].second - l[i] + 1) * (fir + sec) / 2;
		l_mod--;
		r_mod++;
		if(l_mod < r_mod) {
			cout << ans << endl;
		} else {
			ans += area_sum[l_mod];
			ans -= area_sum[r_mod - 1];
			cout << ans << endl;
		}
	}
	return 0;
}
0