概要
level 1: GCD , LCM ,素数判定 , 埃氏筛
level 2 : 整数拆分 exgcd 欧拉筛(线性筛)
`
数学基本巧妙思路
加减妙法:
构建负数 再用减法
基本思路:分两种情况::
1.m=0 没有减号 则全部相加
2.有减号 则构造负数 但减号必须会生效一次 要求最大值 则贪心 舍弃掉最小数(排序)
#include"bits/stdc++.h"
using namespace std;
const int N = 2e5 + 10;
int a[N];
int main()
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n + m + 1; i ++)
{
scanf("%d", &a[i]);
}
int len = n + m + 1;
sort(a + 1, a + 1 + len);
long long res = 0;
if(!m)
{
for(int i = 1; i <= len ;i ++)res += a[i];
}
else
{
res += a[len] - a[1];
for(int i = 2; i < len ;i ++)
res += abs(a[i]);
}
cout << res;
}
容斥原理
提示:简记容斥原理:奇加偶减。
已知:需要求解的是不含"c",“o”,"w"的字符串的数量。
计算贡献:将题目要求换一种表述方式。
求解的个数:不含"c"或者不含"o"或者不含"w"的字符串的数量。
So
不含"c"或者不含"o"或者不含"w"的数量 = 不含"c"的数量 + 不含"o"的数量 + 不含"w"的数量 − 不含"c"并且不含"o"的数量 − 不含"o"并且不含"w"的数量 − 不含"c"并且不含"w"的数量 + 不含"c"并且不含"o"并且不含"w"的数量。
由于不含一个字母的个数都相同,不含两个字母的个数也相同。
所以等式变为:
不含"c"或者不含"o"或者不含"w"的数量 = 3× ×不含"c"的数量 − 3×不含"c"并且不含"o"的数量 + 不含"c"并且不含"o"并且不含"w"的数量
答案=
C(3,2)*可能含有两个非法字符的方案数
-C(3,1)*可能含有一个非法字符的方案数
+C(3,0)*不含非法字符的方案数
=C(3,2)*pow(25,n) - C(3,1)*pow(24,n) + C(3,0)*pow(23,n);
直接快速幂求解,复杂度logn。
代码实现
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll qmi(int x,int y){
ll res=0;
while(y){
if(y&1)res=res*x%mod;
a=a*a%mod;
y>>=1;
}
return res;
}
int main()
{
int n;
cin>>n;
ll ans=3*qmi(25,n)%mod-3*qmi(24,n)%mod+qmi(23,n)%mod;
ans=(ans%mod+mod)%mod;
cout<<ans<<endl;
return 0;
}
法二:dp
dp[i][j] 前i个字符出现了 j 种 禁忌字符,注意是种,所以递推方程就不难推了。
复杂度On。
#include<bits/stdc++.h>
using namespace std;
const int maxx=2e5+7;
const long long ll;
const ll mod=1e9+7;
ll dp[maxx][3];//含义为前i个里面包含有j个禁忌字符
int n;
int main()
{
cin>>n;
dp[1][0]=23;dp[1][1]=3;dp[1][2]=0;
for(int i=2;i<=n;i++){
dp[i][0]=dp[i-1][0]*23;
dp[i][1]=dp[i-1][0]*3+dp[i-1][1]*25;
dp[i][2]=dp[i-1][1]*2+dp[i-1][2]*25;
}
printf("%lld\n",(dp[n][0]+dp[n][1]+dp[n][2])%mod);
}
数论
质数判定
时间复杂度为o(log n /3)
bool isPrime_3( int num )
{
//两个较小数另外处理
if(num ==2|| num==3 )
return 1 ;
//不在6的倍数两侧的一定不是质数
if(num %6!= 1&&num %6!= 5)
return 0 ;
int tmp =sqrt( num);
//在6的倍数两侧的也可能不是质数
for(int i= 5;i <=tmp; i+=6 )
if(num %i== 0||num %(i+ 2)==0 )
return 0 ;
//排除所有,剩余的是质数
return 1 ;
}
扩展欧几里得算法
例一:包子凑数(扩展欧几里得+完全背包)
例二:
解题思路: