板子:
int run(int year) { if((year%4==0&&year%100!=0)||(year%400==0)) return 1; else return 0; }
**蓝桥杯函数:**
全排列函数:next_permutation(a.begin(), a.end())
stoi(s) 将字符串s转为数字
二分查找:binary_search(arr[],arr[]+size , indx)
__builtin_popcount(n) :n的⼆进制中1的个数
__builtin_ffs(n):返回最低的非 0 位的下标,下标从 1 还是计数,0未定义
__builtin_clz(n):返回从最高位开始连续的 0 的个数
__builtin_ctz(n):返回从最低位开始的连续的 0 的个数;如果传入 0 则行为未定义
1.判断一个数字x二进制下第i位是不是等于1。(最低第1位)
方法:if(((1<<(i−1))&x)>0) 将1左移i-1位,相当于制造了一个只有第i位 上是1,其他位上都是0的二进制数。然后与x做与运算,如果结果>0, 说明x第i位上是1,反之则是0。
2.将一个数字x二进制下第i位更改成1。
方法:x=x|(1<<(i−1)) 证明方法与1类似。
3.将一个数字x二进制下第i位更改成0。
方法:x=x&~(1<<(i−1))
4.把一个数字二进制下最靠右的第一个1去掉。
方法:x=x&(x−1)
按位或运算符(|)
运算规则:参加运算的两个数只要两个数中的一个为1,结果就为1。
即 0 | 0= 0 , 1 | 0= 1 , 0 | 1= 1 , 1 | 1= 1 。
异或运算符(^)
运算规则:参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
即 0 ^ 0=0 , 0 ^ 1= 1 , 1 ^ 0= 1 , 1 ^ 1= 0 。
按位与运算符(&)
运算规则:只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算)
即 0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。
fill()函数参数:fill(first,last,val); 、//可以相当于memset赋值 ,赋值随意。
ceil() 函数向上舍入为最接近的整数。
**提示**:如需向下舍入为最接近的整数,请查看 floor() 函数。
**提示**:如需对浮点数进行四舍五入,请查看 round() 函数。
初始化:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define CAS int cas;cin>>cas;while(cas--)
#define mem(a,b) memset(a,b,sizeof(a))
#define f(i,l,h) for(int i=l;i<=h;++i)
#define eps 1e-9
#define pi acos(-1.0)
#define pb push_back
#define se second
#define fi first
const int maxn=500005;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> pii;
typedef long long ll;
using namespace std;
快读:
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void Prin(ll x){if(x < 0){putchar('-');x = -x;}if(x > 9) Prin(x / 10);putchar(x % 10 + '0');}
usin
inline int read(){//快读,可快了
int x=0,f=0;char ch=getchar();
while(!isdigit(ch))f|=ch=='-',ch=getchar();
while(isdigit(ch))x=x*10+(ch^48),ch=getchar();
return f?-x:x;
}
快速幂:
ll quick(ll a,ll b,ll m) {
ll ans=1;
while(b) {
if(b&1)
ans=(a*ans)%m;
a=(a*a)%m;
b>>=1;
}
return ans;
}
GCD/LCM:
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a % b);
}
ll lcm(ll a, ll b) {
return a / gcd(a, b) * b;
}
组合数:
#define mod 1000000007
ll fac[maxn],inv[maxn];
void init(){
fac[0] = inv[0] = 1;
fac[1] = inv[1] = 1;
for(int i = 2; i <= maxn - 9; ++i)// 一定要从2开始
fac[i] = fac[i-1] * i % mod,
inv[i] = (mod - mod / i) * inv[mod % i] % mod;
for(int i = 1; i <= maxn - 9; ++i)
inv[i] = inv[i] * inv[i-1] % mod;
}
ll c(int n,int m){
if(m>n||m<0) return 0;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
欧拉筛:
const int maxx = 1e6+10;
int prime[maxx+10];
bool vis[maxx+10];
int k=0;
void init(){
vis[0]=vis[1]=1;
for(int i=2;i<=maxx;i++){
if(vis[i]==0)prime[++k]=i,vis[i]=1;
for(int j=1;i*prime[j]<=maxx&&j<=k;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
大整数质因数分解:
const int MAXN = 10000005 ;
#define int64_t long long
int64_t mulEx(int64_t a , int64_t b , int64_t Mod) {///logn快速乘
if(!a) return 0 ;
int64_t ans(0) ;
while(b)
{
if(b & 1) ans = (ans + a) % Mod;
a <<= 1 ;
a %= Mod ;
b >>= 1 ;
}
return ans ;
}
int64_t powEx(int64_t base , int64_t n , int64_t Mod)
{///快速幂
int64_t ans(1) ;
while(n)
{
if(n & 1) ans = mulEx(ans , base , Mod) ;
base = mulEx(base , base , Mod) ;
n >>= 1 ;
}
return ans ;
}
bool check(int64_t a , int64_t d , int64_t n)
{
if(n == a) return true ;
while(~d & 1) d >>= 1 ;
int64_t t = powEx(a , d , n) ;
while(d < n - 1 && t != 1 && t != n - 1)
{
t = mulEx(t , t , n) ;
d <<= 1 ;
}
return (d & 1) || t == n - 1 ;
}
bool isP(int64_t n)
{ ///判断大数是否是质数
if(n == 2) return true ;
if(n < 2 || 0 == (n & 1)) return false ;
static int p[5] = {2 , 3 , 7 , 61 , 24251} ;
for(int i = 0 ; i < 5 ; ++ i) if(!check(p[i] , n - 1 , n)) return false ;
return true ;
}
int64_t gcd(int64_t a , int64_t b)
{
if(a < 0) return gcd(-a , b) ;
return b ? gcd(b , a - b * (a / b)) : a ;
}
int64_t Pollard_rho(int64_t n , int64_t c)
{///大数分解质因数
int64_t i = 1 , k = 2 , x = rand() % n , y = x ;
while(true)
{
x = (mulEx(x , x , n) + c) % n ;
int64_t d = gcd(y - x , n) ;
if(d != 1 && d != n) return d ;
if(y == x) return n ;
if(++ i == k)
{
y = x ;
k <<= 1 ;
}
}
}
vector<int64_t>Fac, factCnt ;
///Fac存的是质因子,大小不一定按照顺序,有重复
void factorization(int64_t n)
{
if(n==1) return ;
if(isP(n))
{
Fac.push_back(n) ;
return ;
}
int64_t p(n) ;
while(p >= n) p = Pollard_rho(p , rand() % (n - 1) + 1) ;
factorization(p) ;
factorization(n / p) ;
}
map<int64_t , int64_t> factMap ;
///遍历map的first表示因子,second表示次数
void getFactor(int64_t x)
{///不用判断是否是质数,但是比较费时间
/**因此最好先判断一下是否是质数**/
srand(time(0)) ;
//factCnt = 0 ;
factMap.clear() ;
factorization(x) ;
for(int i = 0; i < Fac.size(); ++i) ++ factMap[Fac[i]] ;
}
分解质因数:
//求每个数最小质因子
int cnt=0,lim=1e6+5;
void getprime(){
int cnt=0;
isprime[1]=1;
for(int i=2;i<=lim;i++){
if(isprime[i]==0){
prime[++cnt]=i,isprime[i]=i;
}
for(int j=1;j<=cnt&&i*prime[j]<=lim;j++){
isprime[i*prime[j]]=prime[j];
if(i%prime[j]==0){
break;
}
}
}
}
//分解质因数
while(x!=1) {
++pz[isprime[x]];
x/=isprime[x];
}
求 (1e12) 内质数:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
//通过知道前面的 n^1/3 的质数可以推断后面n^2/3的质数所以可以适当减小
const int N = 9e3;
const int M = 2; //为了减小内存可以不过是质数
const int PM = 2 * 3 * 5; //为了减小内存可以不过要按质数减小如去掉17
ll n;
bool np[N];
int p