ACM板子


板子:

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GGood_Name

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值