1. 程式人生 > >CQOI2007 餘數求和

CQOI2007 餘數求和

傳送門

或許這也算是道神仙題?

題目描述非常直白,我們把式子轉化一下,其實就是求n*k - ∑(k/i) * i。

而k/i是可以使用除法分塊來做的……假設t = k / i,如果t = 0,那麼它的末端就是n,這個很顯然,如果不等於0的話,那麼末端就是k / t。

之後我們就神奇的過了這道題……

程式碼極短。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include
<vector> #include<queue> #define pb push_back #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar('\n') using namespace std; typedef long long ll; const int M = 40005; const int N = 2000005; const int INF = 1000000009; const ll mod = 51123987
; ll read() { ll ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return ans * op; } ll n,k,ans,l
= 1,r,t; int main() { n = read(),k = read(); while(l <= n) { t = k / l; r = (t) ? min(k / t,n) : n,ans += t * (r - l + 1) * (l + r) >> 1; l = r + 1; } printf("%lld\n",n * k - ans); return 0; }