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; }
当你意识到,每个上一秒都成为永恒。