B

来源:互联网 发布:三鹿奶粉危机公关知乎 编辑:程序博客网 时间:2024/04/30 11:28

题意:给出n,k;

k mod i  =k-i*(k/i)
= n*k - (1*(k/1)+2*(k/2)+3*(k/3)+.....n*(k/n))

我们发现  当 i >k 时 k/i=0,不必计算

k/k, k/(k-1),............. k/(k/2+1)   k/i=1;        即k*(k/k) + (k-1)*( k/(k-1))+.............(k/2+1)*( k/(k/2+1))= 1*西柯玛(k~(k/2+1))

k/(k/2) , k/(k/2-1) ,............,k/(k/3+1)  k/i=2;      (k/2)*(k/(k/2) ) + (k/2-1)*(k/(k/2-1) )+............(k/3+1)*(k/(k/3+1))= 2*西柯玛((k/2)~(k/3+1))

往后类推,需要计算的会比较小,应该是log级别的复杂度,太菜,不会算,也不知道对不对,希望知道的大佬留言区教教我

代码风格也丑的一匹。。。。。。。

#include<stdio.h>using  namespace std;long long p(long long b,long long e){if((b+e)&1) return ((e-b+1)/2)*(b+e);return ((b+e)/2)*(e-b+1); }int main(){long long n,k,a,b;while(~scanf("%lld%lld",&n,&k)){    long long ans=n*k;// (k mod (1-n))//  k-i*(k/i)//  n*k-(1*(k/1)+2*(k/2)+3*(k/3)+.....n*(k/n))// n*k-(1*(k/1)+2*(k/2)+3*(k/3)+..... +((k/2)+1)*(k/(2)+1).....k*(k/k)+0+0+000000.....) long long i=2; while(1) { if(k/i<n) { if(n>k) b=k+1;else b=n+1;   break; } i++; }  for(;;i++){   a=b-1;   b=(k/i+1);   if(a==b) break;   ans-=((i-1)*p(b,a));} for(i=a;i>=1;i--)ans-=(i*(k/i));printf("%lld\n",ans);}return 0; } 


分块模板

#include<stdio.h>#include<algorithm>using namespace std;long long sum(long long b,long long e)  {      if((b+e)&1) return ((e-b+1)/2)*(b+e);      return ((b+e)/2)*(e-b+1);   } long long clac(long long k,long long n){    long long ans=0;    int Min=min(k,n);for (int i = 1, la = 0; i <= Min; i = la + 1)      {          la=k/(k/i);        if(la>Min) la=Min;       // printf("i=%d la=%d\n",i,la);        ans +=sum(i,la)*(k/i);    //区间[i,la]为一块     }      return ans; }int main(){long long n,k,ans;while(~scanf("%lld%lld",&n,&k)){ans=n*k;ans-=clac(k,n);printf("%lld\n",ans);}return 0;}



 

原创粉丝点击