[关闭]
@lychee123 2017-12-04T15:30:52.000000Z 字数 2302 阅读 865

小知识点

数论部分

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int mod=1e9+7;
  4. const int maxn=1e5+5;
  5. int f[maxn];
  6. void init()
  7. {
  8. f[0]=1;
  9. for(int i=1;i<maxn;i++)
  10. {
  11. f[i]=0;
  12. int flag;
  13. for(int j=1;;j++)
  14. {
  15. int temp1=i-j*(3*j-1)/2;
  16. int temp2=i-j*(3*j+1)/2;
  17. if(j%2==1)
  18. flag=1;
  19. else
  20. flag=-1;
  21. if(temp1<0&&temp2<0)
  22. break;
  23. if(temp1>=0)
  24. {
  25. f[i]+=flag*f[temp1];
  26. f[i]%=mod;
  27. }
  28. if(temp2>=0)
  29. {
  30. f[i]+=flag*f[temp2];
  31. f[i]%=mod;
  32. }
  33. }
  34. if(f[i]<0)
  35. f[i]+=mod;
  36. }
  37. }
  38. int main()
  39. {
  40. init();
  41. int t;
  42. scanf("%d",&t);
  43. while(t--)
  44. {
  45. int n;
  46. scanf("%d",&n);
  47. printf("%d\n",f[n]);
  48. }
  49. return 0;
  50. }
  51. /*
  52. 题意:
  53. 问有多少种不同的方式用数字拼成n
  54. 5=1+1+1+1+1=1+1+1+2=1+2+2=1+1+3=2+3=1+4=5(共七种)
  55. 五边形数定理
  56. 公式:f[n]=∑(-1)^(k-1)*(f[n-k*(3*k-1)/2]+f[n-k*(3*k+1)/2])
  57. 其中n-k*(3*k-1)/2>=0,n-k*(3*k+1)/2>=0
  58. 分开判断
  59. */

随机函数的使用

  1. mt19937 gen(time(NULL));//随机的时间函数要写在外面才有用
  2. void init()
  3. {
  4. uniform_int_distribution<int> dis(1, n);//这个位置的两个int表示数据类型,如果要随机实数就改成real
  5. int flag=1;
  6. while(flag)
  7. {
  8. pos1=dis(gen);
  9. pos2=dis(gen);
  10. pos3=dis(gen);
  11. if(pos1!=pos2&&pos1!=pos3&&pos2!=pos3)
  12. flag=0;
  13. if(!check())
  14. flag=1;
  15. //printf("随机 %d %d %d\n",pos1,pos2,pos3);
  16. }
  17. }
  1. 欧拉函数分解素因子
  2. void phi(ll n)
  3. {
  4. num=0;
  5. for(int i=2;i*i<=n;i++)
  6. {
  7. if(n&&n%i==0)
  8. {
  9. while(n%i==0)
  10. {
  11. n/=i;
  12. }
  13. pri[num++]=i;
  14. }
  15. }
  16. if(n>1) pri[num++]=n;
  17. }
  18. ///////
  19. 欧拉函数求个数(数组开不下可以用)
  20. int Phi(int n)
  21. {
  22. int i,p,ans=1;
  23. for(i=2;i*i<=n;i++)
  24. if(n&&n%i==0)
  25. {
  26. p=1;
  27. while(n&&n%i==0)
  28. {
  29. p*=i;
  30. n/=i;
  31. }
  32. ans*=p/i*(i-1);
  33. }
  34. if(n>1)
  35. ans*=(n-1);
  36. return ans;
  37. }
  38. //欧拉函数求区间内质因子个数
  39. void init()
  40. {
  41. memset(num,0,sizeof(num));
  42. memset(isprime,true,sizeof(isprime));
  43. isprime[1]=false;
  44. for(int i=2; i<=N; i++)
  45. {
  46. if(isprime[i])
  47. {
  48. for(int j=i; j<=N; j+=i)
  49. {
  50. int temp=j;
  51. while(temp%i==0)
  52. {
  53. num[j]++;
  54. temp/=i;
  55. }
  56. isprime[j]=false;
  57. }
  58. }
  59. }
  60. for(int i=2; i<=N; i++)
  61. num[i]=num[i]+num[i-1];
  62. }
  1. //中国剩余定理
  2. #include<bits/stdc++.h>
  3. typedef long long LL;
  4. using namespace std;
  5. LL a[11],m[11];
  6. //处理x%m=a对于不同的m,a解出最小的x(对于m不互质的情况也可以处理)
  7. LL exgcd(LL a, LL b, LL &x, LL &y)
  8. {
  9. if (b == 0)
  10. {
  11. x = 1;
  12. y = 0;
  13. return a;
  14. }
  15. LL ret = exgcd(b, a%b, x, y);
  16. LL t = x;
  17. x = y;
  18. y = t - (a / b)*y;
  19. return ret;
  20. }
  21. LL lcm(LL a, LL b)
  22. {
  23. return a / __gcd(a, b)*b;
  24. }
  25. LL CRT(LL m[], LL a[], int n)//n表示方程组个数
  26. {
  27. LL X = a[1];
  28. LL LCM = m[1];
  29. for (int i = 2; i <= n; i++)
  30. {
  31. LL x, y;
  32. a[i] -= X;
  33. a[i] = (a[i] % m[i] + m[i]) % m[i];
  34. int d = exgcd(LCM, m[i], x, y);
  35. if (a[i] % d) return -1;
  36. x *= a[i] / d;
  37. x = (x % (m[i] / d) + m[i] / d) % (m[i] / d);
  38. X += LCM*x;
  39. LCM = lcm(LCM, m[i]);
  40. }
  41. return X;//返回值-1代表无解,其余返回最小值,可能为0
  42. }
  43. int main()
  44. {
  45. LL p,e,i,d;
  46. int tt=0;
  47. while(~scanf("%lld%lld%lld%lld",&p,&e,&i,&d))
  48. {
  49. if(p==-1&&e==-1&&i==-1&&d==-1)
  50. break;
  51. m[1]=23,m[2]=28,m[3]=33;
  52. a[1]=p,a[2]=e,a[3]=i;
  53. LL ans=CRT(m,a,3);
  54. while(ans<=d) ans+=23*28*33;
  55. printf("Case %d: the next triple peak occurs in %lld days.\n",++tt,ans-d);
  56. }
  57. return 0;
  58. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注