当前位置: 代码迷 >> 综合 >> hdu2620 Ice Rain(数论分块)
  详细解决方案

hdu2620 Ice Rain(数论分块)

热度:59   发布时间:2024-01-24 07:13:44.0

题意:
G i v e n   t w o   i n t e g e r s   n , k ( 1 < = n , k < = 109 ) . Given \ two \ integers\ n, k(1 <= n, k <= 109). ,求
在这里插入图片描述
思路:数论分块。
i = 1 n k % i \sum_{i=1}^nk \% i
= i = 1 n ( k ? ? k i ? ? i ) =\sum_{i=1}^{n}(k - \left\lfloor\\\tfrac{k}{i}\right\rfloor*i)

= n ? k ? i = 1 n ( ? k i ? ? i ) =n*k-\sum_{i=1}^{n}(\left\lfloor\\\tfrac{k}{i}\right\rfloor*i)
有数论分块可得,
对于每一个 l l ,有一个对应的右端点 n ? n l ? \dfrac{n}{\left\lfloor\\\tfrac{n}{l}\right\rfloor} ,在这个区间 [ l , r ] [l,r] 中的值都是 n l \dfrac{n}{l}
故上述 [ 1 , n ] [1,n] 的区间可以划分为多个小区间,每个小区间 ? k i ? \left\lfloor\\\tfrac{k}{i}\right\rfloor 的值都相等。
故令 t = ? k i ? t=\left\lfloor\\\tfrac{k}{i}\right\rfloor
那么
n ? k ? i = 1 n ( ? k i ? ? i ) n*k-\sum_{i=1}^{n}(\left\lfloor\\\tfrac{k}{i}\right\rfloor*i)

= n ? k ? ( t ? l r i ) =n*k-\sum(t*\sum_{l}^{r}i)
A C   C o d e : AC \ Code:

#include<iostream>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<set>
#include<stack>
#include<cstdio>
#include<sstream>
#include<vector>
#include<bitset>
#include<algorithm>using namespace std;
#define read(x) scanf("%d",&x)
#define Read(x,y) scanf("%d%d",&x,&y)
#define gc(x) scanf(" %c",&x);
#define mmt(x,y) memset(x,y,sizeof x)
#define write(x) printf("%d\n",x)
#define pii pair<int,int>
#define INF 0x3f3f3f3f 
#define ll long long
const int N = 100000 + 100;
const int M = 1e6 + 1005;
typedef long long LL;int main(){ll  n,m;while(cin>>n>>m){ll ans = m * n;n = min(n,m);for(ll l = 1,r = 0;l <= n;l = r + 1){r = m/(m/l);if(r > n)  r = n;ll tmp = m/l *(l + r)*(r - l + 1)/2;ans -= tmp;}cout<<ans<<endl;}}