buerdepepeqi的模板

头文件

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
LL read() {
int 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 * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
const double eps = 1e-8;
const int mod = 1e9+7;
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;

数学

费马小定理

a是不能被质数p整除的正整数,则有a^(p-1)≡ 1 mod p,即a^(p-1) mod p=1;
推论:对于不能被质数p整除的正整数a,有a^p≡ a mod p
a^b%p=a^(b%(p-1))%p

逆元

/*O(n)打表求1~n的逆元*/
LL inv[maxn];
void init() {
inv[1] = 1;
for (int i = 2; i < maxn; i++) inv[i] = inv[mod % i] * (mod - mod / i) % mod;
}

矩阵快速幂

struct matrix {//矩阵
int n;//长
int m;//宽
long long a[105][105];
matrix() {//构造函数
n = 2;
m = 2;
memset(a, 0, sizeof(a));
}
matrix(int x, int y) {
n = x;
m = y;
memset(a, 0, sizeof(a));
}
void print() {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
}
void setv(int x) {//初始化
if(x == 0) {
memset(a, 0, sizeof(a));
}
if(x == 1) {
memset(a, 0, sizeof(a));
for(int i = 1; i <= n; i++) a[i][i] = 1;
}
}
friend matrix operator *(matrix x, matrix y) { //矩阵乘法
matrix tmp = matrix(x.n, y.m);
for(int i = 1; i <= x.n; i++) {
for(int j = 1; j <= y.m; j++) {
tmp.a[i][j] = 0;
for(int k = 1; k <= y.n; k++) {
tmp.a[i][j] += (x.a[i][k] * y.a[k][j]) % mod;
}
tmp.a[i][j] %= mod;
}
}
return tmp;
}
};
matrix fast_pow(matrix x, long long k) { //矩阵快速幂
matrix ans = matrix(n, n);
ans.setv(1);//初始化为1
while(k > 0) { //类似整数快速幂
if(k & 1) {
ans = ans * x;
}
k >>= 1;
x = x * x;
}
return ans;
}

欧拉定理和欧拉函数

欧拉函数phi(m):当m>1是,phi(m)表示比m小且与m互质的正整数个数
欧拉定理:a^phi(n) = 1 mod n
a^x = a^(x % phi(p) + p) (mod p)
//打表
int b[N],prime[N],phi[N];
void init(){ //求欧拉函数和素数
int i,j,k,c=0;
memset(b,0,sizeof(b));
for(i=2;i<N;i++){
if(b[i]==0){
prime[++c]=i;
phi[i]=i-1;
}
for(j=1;(j<=c)&&(k=i*prime[j])<N;j++){
b[k]=1;
if(i%prime[j]) phi[prime[j]*i]=phi[i]*(prime[j]-1);
else phi[prime[j]*i]=phi[i]*prime[j];
}
}
}
//直接计算欧拉函数
int phi (int n) {
int res = n;
for (int i = 2; i * i <= n; ++i) {
if (n % i == 0) {
res -= res / i;
while (n % i == 0) n /= i;
}
}
return n > 1 ? res / n * (n - 1) : res;
}
//欧拉函数递归调用
//计算dp[i] = 2^dp[i+1] % mod,需要先计算mod的phi,以及phi(mod)的phi直到为1
//dp[i] = 2^(dp[i+1]%phi(mod)+phi(mod)) %mod
const int MX = 1e5 + 5;
const ll mod = 1e9 + 7;
ll m[50], dp[MX][50];
int sz, n;
int Phi (int n) {
int res = n;
for (int i = 2; i * i <= n; ++i) {
if (n % i == 0) {
res -= res / i;
while (n % i == 0) n /= i;
}
}
return n > 1 ? res / n * (n - 1) : res;
}
void init() {
int x = mod;
sz = 0;
m[++sz] = x;
while (x != 1) m[++sz] = Phi (x), x = m[sz], cout << x << endl;
}
ll pow (ll a, ll b, ll m) {
ll ret = 1;
while (b) {
if (b & 1) ret = ret * a % m;
a = a * a % m;
b >>= 1;
}
return ret;
}
int main() {
init();
for (int i = 1; i <= n; i++) {
for (int j = 1; j < sz; j++) {
dp[i][j] = pow (2ll, dp[i - 1][j + 1], m[j]) * 3 - 3;
while (dp[i][j] < 0) dp[i][j] += m[j];
while (dp[i][j] >= m[j]) dp[i][j] -= m[j];
}
}
printf ("%lld\n", dp[n][1] % m[1]);
}

扩展欧几里得定理

//递归
LL ex_gcd(LL a, LL b, LL &x, LL &y) {
if(b == 0) {
x = 1, y = 0;
return a;
}
int d = ex_gcd(b, a % b, x, y);
int z = x;
x = y;
y = z - y * (a / b);
return d;
}
//非递归
//返回值为 gcd 以及 a,b 的系数
pair<ll, PLL> exgcd(ll a,ll b){
valarray<ll>equation[2] = {{a,1,0},{b,0,1}};
while (equation[1][0]) {
ll q = equation[0][0]/equation[1][0];
equation[0] -= q * equation[1];
swap(equation[0], equation[1]);
}
return MP(equation[0][0],MP(equation[0][1],equation[0][2]));
}

组合数

1、普通组合数

void gcd(LL a, LL b, LL &d, LL &x, LL &y) {
if(!b) {
d = a;
x = 1;
y = 0;
} else {
gcd(b, a % b, d, y, x);
y -= x * (a / b);
}
}
LL inv(LL a, LL n) {
LL d, x, y;
gcd(a, n, d, x, y);
return (x % n + n) % n;
}
LL fac[maxn], fav[maxn];
LL C(LL n, LL m) {
return fac[n] * fav[m] % mod * fav[n - m] % mod;
}
void init() {
fac[0] = 1; fav[0] = 1;
for(int i = 1; i < maxn; i++)fac[i] = fac[i - 1] * i % mod;
for(int i = 1; i < maxn; i++)fav[i] = inv(fac[i], mod);
}

2、Lucas组合数

LL p;
LL n, m;
LL fac[maxn];
LL pow(LL y, int z, int p) {
y %= p; LL ans = 1;
for(int i = z; i; i >>= 1, y = y * y % p)if(i & 1)ans = ans * y % p;
return ans;
}
LL C(LL n, LL m) {
if(m > n)return 0;
return ((fac[n] * pow(fac[m], p - 2, p)) % p * pow(fac[n - m], p - 2, p) % p);
}
LL Lucas(LL n, LL m) {
if(!m)return 1;
return C(n % p, m % p) * Lucas(n / p, m / p) % p;
}
int main() {
scanf("%lld%lld%lld", &n, &m, &p);
fac[0] = 1;
for(int i = 1; i <= p; i++) {
fac[i] = fac[i - 1] * i % p;
}
printf("%lld\n", Lucas(n, m) );
return 0;
}

3、卡特兰数

卡特兰数是一种经典的组合数,经常出现在各种计算中,其前几项为 :

1, 2, 5, 14, 42,

132, 429, 1430, 4862, 16796,

58786, 208012, 742900, 2674440, 9694845,

35357670, 129644790, 477638700, 1767263190,

6564120420, 24466267020, 91482563640, 343059613650, 1289904147324,

4861946401452, ...

\[C_n=\frac{(2n)!}{(n+1)!n!}
\]

卡特兰数满足如下递归

\[C_0=0\quad and \quad C_{n+1}=\frac{2(2n+1)}{n+2}C_n\\
C_0=1\quad and \quad C_{n+1}=\sum_{i=0}^{n}C_iC_{n-i}\quad n>=0
\]

卡特兰数的渐进增长为

\[C_n=> \frac{4^n}{n^{3/2}\sqrt{\pi}}
\]

所有的奇卡塔兰数Cn都满足n = 2^k − 1。

所有其他的卡塔兰数都是偶数。

卡特兰数的经典问题
  1. n个左括号与n个右括号组成的合法序列的数量为卡特兰数
  2. 1,2,···,n经过一个栈,形成的合法的出栈序列的数量为卡特兰数
  3. n个节点构成不同的二叉树的数量为卡特兰数
  4. 在平面直角坐标系上,每一步只能向上走或向右走,从(0,0)走到(n,n)并且除了两个端点外不能接触直线y=x的路线数量为2*Cat_n-1
  5. Cn表示通过连结顶点而将n + 2边的凸多边形分成三角形的方法个数
  6. Cn表示集合{1, …, n}的不交叉划分的个数. 其中每个段落的长度为2
  7. Cn表示用n个长方形填充一个高度为n的阶梯状图形的方法个数

    下图为 n = 4的情况:

4、错排公式

\[D(n)=(n-1)*[D(n-1) +D(n-2)]
\]

约瑟夫环

//最后一个报号的人
int main(){
int n, m, i, s = 0;
scanf("%d%d", &n, &m);
for (i = 2; i <= n; i++)
s = (s + m) % i;
printf ("\nThe winner is %d\n", s+1);
}
//第k个出去的人
#include<bits/stdc++.h> using namespace std; int main(){
int n,k;
while(scanf("%d%d",&n,&k)==2){//n个人第k个人走,最后一个人是谁
int t; scanf("%d",&t);
while(t--){
int q; scanf("%d",&q);
long long N = (long long)q*k;
while(N>n){
N = (N-n-1)/(k-1)+N-n;
}
printf("%d%c",(int)N," \n"[!t]);
}
}
return 0;
}

莫比乌斯函数

//线性筛求莫比乌斯函数
int mu[maxn];
int prime[maxn];
int not_prime[maxn];
int n,tot;
void Mobiwus(){
mu[1] = 1;
for(int i = 2; i <= n; i++) {
if(!not_prime[i]) {
prime[++tot] = i;
mu[i] = -1;
}
for(int j = 1; prime[j]*i <= n; j++) {
not_prime[prime[j]*i] = 1;
if(i % prime[j] == 0) {
mu[prime[j]*i] = 0;
break;
}
mu[prime[j]*i] = -mu[i];
}
}
}

BM递推式

namespace linear_seq {
#define pb push_back
#define SZ(x) ((int)(x).size())
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(a)-1;i>=(b);--i)
typedef vector<int> VI;
const int N = 10010;
const LL mod = 1e9 + 7;
LL res[N], base[N], cnt[N], val[N];
LL power(LL a, LL b) {
LL ret = 1; a %= mod;
while(b) {
if(b & 1)ret = ret * a % mod;
a = a * a % mod;
b >>= 1;
}
return ret;
}
vector<int> v;
void mul(LL *a, LL *b, int k) {
rep(i, 0, k + k) cnt[i] = 0;
rep(i, 0, k) if (a[i]) rep(j, 0, k) cnt[i + j] = (cnt[i + j] + a[i] * b[j]) % mod;
per(i, k + k, k) if (cnt[i]) rep(j, 0, SZ(v))
cnt[i - k + v[j]] = (cnt[i - k + v[j]] - cnt[i] * val[v[j]]) % mod;
rep(i, 0, k) a[i] = cnt[i];
}
int solve(LL n, VI a, VI b) { // a系数 b初值 b[n+1]=a[0]*b[n]+...
LL ans = 0, pnt = 0;
int k = SZ(a);
rep(i, 0, k) val[k - 1 - i] = -a[i]; val[k] = 1;
v.clear();
rep(i, 0, k) if (val[i] != 0) v.push_back(i);
rep(i, 0, k) res[i] = base[i] = 0;
res[0] = 1;
while ((1LL << pnt) <= n) pnt++;
per(p, pnt + 1, 0) {
mul(res, res, k);
if ((n >> p) & 1) {
per(i, k, 0) res[i + 1] = res[i]; res[0] = 0;
rep(j, 0, SZ(v)) res[v[j]] = (res[v[j]] - res[k] * val[v[j]]) % mod;
}
}
rep(i, 0, k) ans = (ans + res[i] * b[i]) % mod;
if (ans < 0) ans += mod;
return ans;
}
VI BM(VI s) {
VI C(1, 1), B(1, 1);
int L = 0, m = 1, b = 1;
rep(n, 0, SZ(s)) {
LL d = 0;
rep(i, 0, L + 1) d = (d + (LL)C[i] * s[n - i]) % mod;
if (d == 0) ++m;
else if (2 * L <= n) {
VI T = C;
LL c = mod - d * power(b, mod - 2) % mod;
while (SZ(C) < SZ(B) + m) C.pb(0);
rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % mod;
L = n + 1 - L; B = T; b = d; m = 1;
} else {
LL c = mod - d * power(b, mod - 2) % mod;
while (SZ(C) < SZ(B) + m) C.pb(0);
rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % mod;
++m;
}
}
return C;
}
int gao(VI a, LL n) {
VI c = BM(a);
c.erase(c.begin());
rep(i, 0, SZ(c)) c[i] = (mod - c[i]) % mod;
return solve(n, c, VI(a.begin(), a.begin() + SZ(c)));
}
};
//用法vector<int>v;
//打表填系数递推
//linear_seq::gao(v, n - 1)

字符串

马拉车

struct Manacher {
int p[maxn << 1], str[maxn << 1];
bool check(int x) {
return x - (x & -x) == 0;
}
bool equal(int x, int y) {
if ((x & 1) != (y & 1)) return false;
return (x & 1) || (check(mask[x >> 1]) && check(mask[y >> 1]) && str[x] == str[y]);
}
int solve(int len) {
int max_right = 0, pos = 0, ret = 0;
for (int i = 1; i <= len; i++) {
p[i] = (max_right > i ? std::min(p[pos + pos - i], max_right - i) : 1);
if ((i & 1) || check(mask[i >> 1])) {
while (equal(i + p[i], i - p[i])) p[i]++;
if (max_right < i + p[i]) pos = i, max_right = i + p[i];
ret += p[i] / 2;
} else p[i] = 2;
}
return ret;
}
} manacher;

图论

三元环

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
vector<int> g[N];
int deg[N], vis[N], n, m, ans;
struct E { int u, v; } e[N * 3];
int main() {
scanf("%d%d", &n, &m);
for(int i = 1 ; i <= m ; ++ i) {
scanf("%d%d", &e[i].u, &e[i].v);
++ deg[e[i].u], ++ deg[e[i].v];
}
for(int i = 1 ; i <= m ; ++ i) {
int u = e[i].u, v = e[i].v;
if(deg[u] < deg[v] || (deg[u] == deg[v] && u > v)) swap(u, v);
g[u].push_back(v);
}
for(int x = 1 ; x <= n ; ++ x) {
for(auto y: g[x]) vis[y] = x;
for(auto y: g[x])
for(auto z: g[y])
if(vis[z] == x)
++ ans;
}
printf("%d\n", ans);
}

小技巧

二进制状态压缩

\[取出整数n在二进制表示下的第k位:(n>>k)\&1\\
取出整数n在二进制表示下的第0 \sim k-1位(后k位):n\&((1<<k)-1)\\
把整数n在二进制表示下第k位取反:n\quad xor\quad(1<<k)\\
对整数n在二进制下表示的第k位赋值1:n|(1<<k)\\
对整数n在二进制表示下的第k为赋值0:n\&(\sim(1<<k))\\
\]

rope的用法

头文件:#include <ext/rope>

命名空间using namespace __gnu_cxx;

定义:rope r;

insert(pos, s)将字符串s插入pos位置

erase(pos, num)从pos开始删除num个字符

copy(pos, len, s)从pos开始len个字符用s代替

substr(pos, len)提取pos开始的len个字符

at(x)访问第x个元素

最新文章

  1. ASP.NET MVC搭建项目后台UI框架—9、服务器端排序
  2. 2014年年度工作总结--IT狂人实录
  3. 说说ASP.NET的表单验证
  4. Solr:文本分析
  5. C#中(int)a和Convert.ToInt32(a)有什么区别
  6. C/S B/S 及WEB工作原理
  7. misc_register、 register_chrdev 的区别总结
  8. XRDP与VNC的关系
  9. tar 基础
  10. query 原理
  11. 初学Log4Net
  12. Oracle数据库悲观锁与乐观锁详解
  13. RoboCup仿真3D TC笔记(2014年合肥中国公开赛 仿真3D比赛环境搭建)
  14. while100以内的偶数
  15. HNOI 2012 永无乡
  16. Flash与EEPROM
  17. Linux内存管理 (2)页表的映射过程
  18. redis启动出错Creating Server TCP listening socket 127.0.0.1:6379: bind: No error(转)
  19. [daily][device][archlinux][trackpoint] 修改指点杆速度/敏捷度
  20. selenium 网络请求

热门文章

  1. C/S和B/S交互 2016-03-19 11:27 1275人阅读 评论(30) 收藏
  2. 字节缓冲流 ( BufferedInputStream / BufferedOutputStream)
  3. oracle HEXTORAW(c1)
  4. Java练习 SDUT-1959_简单枚举类型——植物与颜色
  5. oracle函数 current_timestamp
  6. uva 10566 Crossed Ladders (二分)
  7. zoj 3859 DoIt is Being Flooded (MFSet &amp;&amp; Flood Fill)
  8. html选择题
  9. WebService 基础知识点和用Postman调试
  10. PHP 面试题 一