T一:14682约数个数和
题目要求:给个n求1到其的所有约数个数之和。n <= 100000000 2^24<n<2^32使用数组明显不现实
百度了下思路 :枚举约数,判断他是谁的约数,并记录一共(即他的倍数有多少个),从1到n,sum+=n/i记录
如3约数共是5=3(是1倍数的有三个!!因为数类叠加厉害)+1+1;
#include<iostream>
using namespace std;
int main()
{
int n,sum=0;
cin>>n;
for(int i=1;i<=n;i++)
{
sum+=n/i;
}
cout<<sum<<endl;
return 0;
}
T2:最大字段和问题-动态规划
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
int s[10000055];
//简单dp
int main(){
int ans=0,b=0,maxn=0;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&s[i]);//数据量大使用scanf优化
if(i==1)
maxn=s[i];//初始给max赋值
//开始找最大子序列,只要他的值叠起来不等于0,就可以计算进去
if(ans>0)
ans+=s[i];
else
ans=s[i];//叠到这个的时候,前面的最大值已找到记录在maxn里,现在削减到0,且从现在0为ans新起点叠代
maxn=ans>maxn?ans:maxn; //每叠一次判断一次
}
cout<<maxn;//最后输出最大子段
}
哈尔滨工程大学ACM预热赛C king
第一天可以产a吨粮食,第二天会变成前一天的a倍,以此类推。
n天后大臣准备把这些粮食尽可能多的平均分给b个城池
为了方便,每个城池分到的粮食都是整吨整吨哒!
剩下的粮食国王准备贪污,国王能贪到多少吨粮食呢?
由于数据量过大,直接算会爆炸,应该使用快速幂
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long int t;
cin>>t;
while(t--)
{
long long int a,n,b,ans=1;
cin>>a>>n>>b;
while(n)
{
if(n&1)//存在不为0
ans=(ans*a)%b;//ans乘进去
a=(a*a)%b;//二进制位自增
n>>1;//n/=2改良版
}
cout<<ans<<endl;
}
}
关于快速幂
基于数学里底数的指数相加等于同底数指数相乘
假设我们要求a^b,那么其实b是可以拆成二进制的,该二进制数第i位的权为2^(i-1),例如当b==11时
a11=a(2^0+2^1+2^3)
11的二进制是1011,11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1,因此,我们将a¹¹转化为算 a2^0*a2^1*a2^3,
1 int poww(int a, int b) {
2 int ans = 1, base = a;
3 while (b != 0) {
4 if (b & 1 != 0)
5 ans *= base;
6 base *= base;
7 b >>= 1;
8 }
9 return ans;
10 }
怎么说呢,能用位运算就用位运算,位运算是最快的
一下是老狗的:https://www.acwing.com/solution/AcWing/content/1290/挺详细的
快速幂) O(logb)O(logb)
对于算法的理解还不够深刻,难免有所疏漏,还请大佬不吝赐教
时间复杂度分析:每次对b进行右移操作
感谢评论大佬分享
(a * b ) % p = ((a % p ) * (b % p) ) % p ;
(a + b ) % p = ((a % p ) + (b % p) ) % p ;
证明仅以a * b % p;
a = c1 * p + yu1 ;
b = c2 * p + yu2;
(a * b) % p = (c1 * p + yu1 ) * (c2 * p+ yu2 ) % p = (yu1*yu2)%p;
本题逻辑核心!!
说明:以下a(n)为a^(2^n)
1.对于(a^b)%p式子的展开
a^b=1*a(x1)*a(x2)*a(x3).....
a^b%p=( (1*a(x1)*a(x2)%p) * (a(x3)%p) ) %p
1*a(x1)*a(x2)%p = ( (1*a(x1)%p) * (a(x2)%p) )%p
1*a(x1)%p = ( (1%p) * (a(x1)%p) )%p
所以res初始化值为1%p
算法即是从下向上实现
2.理解a = a *a % p
迭代a: ( res * (a(xn)%p) )%p 其中的a(xn)%p = a(xn-1)*a(xn-1)%p
湘潭:ICPC比赛中,谁通过的题数多,谁排名靠前;在通过题数相同的情况下,谁的罚时少,谁排名靠前;如果前两者都相同,就看最后正确提交的时间,谁早最排名靠前。 现在给你两个队伍的正确通过的题数、罚时和最后正确提交时间,请判断一下,谁的排名更靠前?
#include<iostream>
using namespace std;
int main()
{
int a[7],flag=0,k=1;
for(int i=0;i<6;i++)
cin>>a[i];
for(int j=0;j<3;j++)
{
if(a[j]==a[j+3])
flag=1;
else
{
if(k==1)
a[j]>a[j+3]?flag=2:flag=3;
else
a[j]<a[j+3]?flag=2:flag=3;
}
// switch(flag)
// {
// case 1:continue;
// case 2:cout<<"1"<<endl;break;
// case 3:cout<<"2"<<endl; break;
// }
if(flag==2)
{
cout<<"1"<<endl;
break;
}
if(flag==3)
{
cout<<"2"<<endl;
break;
}
k=2;
}
if(flag==1)
cout<<"God"<<endl;
return 0;
}