除法分块--玄学

一.套路

①推导式子的时候,出现\lfloor\frac{n}{i} \rfloor(向下取整符号),目前已知用来解决因子和问题

②每块l、r尽量用unsigned long long

③n/l为同一块每个数出现次数,r-l+1为同一块区间有多少个数,r=n/(n/l)很玄学,打表可知刚好是每一块的最右端。

因此下一块左端就l=r+1

④时间复杂度\sqrt n

 

二.题目

GYM101652P求因子和

#include 
using namespace std;
typedef unsigned long long ll;

ll l,r; 
ll getsum(ll n)
{
	ll sum=0;
	for(ll l=1;l<=n;l=r+1)//块是紧挨着的,第一次居然写错成r=l+1 
{
	r=n/(n/l);//每块最右端 (找规律得的,玄学) 
	sum+=(n/l)*(l+r)*(r-l+1)/2;//同一块的次数*同一块数的大小之和(是个等差数列) 
}
   return sum; 
}

int main()
{
  ll a,b;
  while(cin>>a>>b)
  cout<

 

LightOJ 1245求n/i的和

#include 
using namespace std;
typedef unsigned long long ll;

ll l,r; 
ll getsum(ll n)
{
	ll sum=0;
	for(int l=1;l<=n;l=r+1)//块是紧挨着的,第一次居然写错成r=l+1 
{
	r=n/(n/l);//每块最右端 (找规律得的,玄学) 
	sum+=(r-l+1)*(n/l);//同一块均贡献n/l*同一块数的长度(即数目) 
}
   return sum; 
}

int main()
{
  ll a,b;
  int T;
  cin>>T;
 for(int i=1;i<=T;i++)
  {
  	  cin>>a;
  	  printf("Case %d: ",i);
  cout<

 

 

你可能感兴趣的:(莫比乌斯&欧拉,—————数论—————,分块)