乱七八糟模板
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define ull unsigned long long
#define PI acos(-1.0)
#define eps 1e-12
#define fi first
#define se second
#define MEM(a,b) memset((a),(b),sizeof(a))
#define mod(x) ((x)%MOD)
#define pii pair
#define wz cout<<"-----"<
const int INF_INT = 2147483647;
const ll INF_LL = 9223372036854775807LL;
const ull INF_ULL = 18446744073709551615Ull;
const ll P = 92540646808111039LL;
const ll maxn = 1e5 + 10, MOD = 1e9 + 7;
const int Move[4][2] = {-1,0,1,0,0,1,0,-1};
const int Move_[8][2] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};
inline int 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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
bool operator < (const node &p) const {
return r > p.r;
}
数据结构
int lowerbit(int x) {
return x & -x;
}
void add(int p, int x) {
while (p < maxn) {
d[p] += x;
p += lowerbit(p);
}
}
int sum(int p) {
int res = 0;
while (p) {
res += d[p];
p -= lowerbit(p);
}
return res;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
数论模板
ll quick_pow(ll a,ll b) {
ll res = 1;
while (b) {
if (b & 1) {
res = a * res;
}
a = a * a;
b >>= 1;
}
return res;
}
#include
#define ll long long
#define mod(x) ((x)%MOD)
using namespace std;
const ll MOD = 1e9 + 7;
struct mat{
ll m[3][3];
}a,ans,unit;
void init() {
memset(unit.m,0,sizeof(unit.m));
memset(a.m,0,sizeof(a.m));
unit.m[0][0] = 1;
unit.m[1][1] = 1;
a.m[0][0] = 3;
a.m[0][1] = 1;
a.m[1][0] = 1;
a.m[1][1] = 3;
}
mat operator * (mat m1,mat m2) {
mat t;
ll r;
for(int i = 0;i < 3;i++) {
for(int j = 0;j < 3;j++) {
r = 0;
for(int k = 0;k < 3;k++) {
r = mod(r*1ll + mod(mod(m1.m[i][k])*1ll*mod(m2.m[k][j])));
}
t.m[i][j] = r;
}
}
return t;
}
mat quick_pow(ll x) {
mat t = unit;
while(x) {
if(x & 1) {
t = t*a;
}
a = a*a;
x >>= 1;
}
return t;
}
int main(){
init();
ans = quick_pow(n);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
bool isp[maxn];
int p[maxn], len;
bool isp[100];
void init() {
int m = (int)sqrt(maxn+0.5);
for(int i = 2;i <= m;i++) {
if(!isp[i]) {
for(int j = i*i;j <= maxn;j += i) {
isp[j] = true;
}
}
}
}
void init() {
isp[0] = isp[1] = true;
for (int i = 2; i < maxn; i++) {
if(!isp[i]) p[++len] = i;
for (int j = 1; j <= len && p[j]*i < maxn; j++) {
isp[i*p[j]] = true;
if (i%p[j] == 0) break;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 欧拉函数
在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1)。
int euler_phi(int n){
int m = (int)sqrt(n + 0.5);
int ans = n;
for (int i = 2;i <= m;i++){
if (n%i == 0){
ans = ans/i*(i-1);
while (n%i == 0) n/=i;
}
}
if(n > 1) ans = ans/n*(n-1);
return ans;
}
void phi_table(int n,int *phi){
for (int i = 1;i <= n;i++) phi[i] = i;
for(int i = 2;i <= n;i++){
if(phi[i] == i){
for(int j = i;j <= n;j+=i){
phi[j] = phi[j]/i*(i-1);
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 欧几里得GCD,扩展~
欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数(greatest common divisor)。
扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a, b) =d(解一定存在,根据数论中的相关定理)。扩展欧几里德常用在求解模线性方程及方程组中。
ll gcd(ll a,ll b) {
return b == 0 ? a : gcd(b, a % b);
}
void exgcd(ll a, ll b, ll &d, ll &x, ll &y) {
if(!b) d=a,x=1,y=0;
else exgcd(b, a % b, d, y, x),y -= x * (a / b);
}
- 逆元
方程ax≡1(mod p),的解称为a关于模p的逆,当gcd(a,p)==1(即a,p互质)时,方程有唯一解,否则无解。
对于一些题目会要求把结果MOD一个数,通常是一个较大的质数,对于加减乘法通过同余定理可以直接拆开计算,但对于(a/b)%MOD这个式子,是不可以写成(a%MOD/b%MOD)%MOD的,但是可以写为(a*b^-1)%MOD,其中b^-1表示b的逆元。
ll getinv (ll a,ll p) {
ll d, x, y;
exgcd (a, p, d, x, y);
return (x + p) % p == 0 ? p : (x + p) % p;
}
中国剩余定理给出了以下的一元线性同余方程组:
假设整数m1,m2, ... ,mn两两互质,则对任意的整数:a1,a2, ... ,an,方程组 有解,即x,扩展剩余定理就是m1,m2···mn,这几个数不两两互质的情况
ll CRT(ll M){
ll sum=0,tmp,v;
for (int i=1;i<=cnt;i++){
tmp=M/m[i];
v=getInv(tmp,m[i]);
sum=(sum+tmp*a[i]*v)%M;
}
return sum;
}
bool merge(ll &a1,ll &m1,ll a2,ll m2){
ll c,d,x,a3,m3;
c=a2-a1;d=__gcd(m1,m2);
if (c%d!=0) return false;
c=c/d;m1=m1/d;m2=m2/d;
x=getinv(m1,m2);
x=(x*c)%m2;
x=x*(m1*d)+a1;
m3=m1*m2*d;
a3=(x%m3+m3)%m3;
a1=a3;m1=m3;
return true;
}
ll ECRT(){
ll A=a[1],M=r[1];
for (int i=2;i<=n;i++)
if (!merge(A,M,a[i],r[i]))
return -1;
return (A%M+M)%M;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 错排公式
问题: 十本不同的书放在书架上。现重新摆放,使每本书都不在原来放的位置。有几种摆法?
这个问题推广一下,就是错排问题,是组合数学中的问题之一。考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。 n个元素的错排数记为D(n)。 研究一个排列错排个数的问题,叫做错排问题或称为更列问题。
ll a = 0,b = 1,c;
for (int i = 3; i <= n; i++) {
c = ((i - 1) * 1ll * (a + b)) % MOD;
a = b;
b = c;
}
printf("%lld\n",c);
- O(n) 求组合数
Ckn=n−k+1kCk−1n Cnk=n−k+1kCnk−1
从开始从左到右递推,注意爆int
C[0] = 1;
for(int i = 1; i <= n; i++)
C[i] = C[i - 1] * (n - i + 1) / i;
-
卡特兰数列
h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,...)
C(m+n,n)−C(m+n,n−1)
-
阶乘逆元
fac[0] = 1;
for (int i = 1; i <= maxn; i++)
fac[i] = mod(fac[i - 1] * i);
rfac[maxn] = qpow(fac[maxn],MOD - 2);
for (int i = maxn;i > 0; i--)
rfac[i - 1] = mod(rfac[i] * i);
图论模板
const int maxn = 1e5 + 10;
vectorint,int> > E[maxn];
int inq[maxn],n,m;
ll dis[maxn];
queue<int> q;
void spfa() {
for(int i = 0;i < maxn;i++) {
dis[i] = 2000000000;
inq[i] = 0;
}
dis[1] = 0;
q.push(1);
while(!q.empty()) {
int t = q.front();
q.pop();inq[t] = 0;
for(int i = 0;i < E[t].size();i++) {
int to = E[t][i].first;
ll di = E[t][i].second;
if(dis[to] > dis[t] + di) {
dis[to] = dis[t] + di;
if(!inq[to]) {
inq[to] = 1;
q.push(to);
}
}
}
}
}
void spfa() {
for (int i = 0; i < maxn; i++) dis[i] = INF;
deque<int> q;
dis[s] = 0;
q.push_back(s);
while (!q.empty()) {
int from = q.front();
q.pop_front();
inq[from] = 0;
for (int i = 0; i < E[from].size(); i++) {
int to = E[from][i].first;
int di = E[from][i].second;
if(dis[to] > dis[from] + di) {
dis[to] = dis[from] + di;
if(inq[to] == 0) {
inq[to] = 1;
if(q.size() && dis[to] < dis[from]) {
q.push_front(to);
} else {
q.push_back(to);
}
}
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 单源最短路 迪杰斯特拉 dijkstra
队列优化
const int maxn = 1e5 + 10;
vectorint,int> > E[maxn];
int n,m,dis[maxn];
priority_queueint,int> > q;
void dij() {
for(int i = 0;i < maxn;++i) {
dis[i] = 1e9;
}
dis[1] = 0;
q.push(make_pair(0,1));
while (!q.empty()) {
int t = q.top().second;
q.pop();
for(int i = 0;i < E[t].size();++i) {
int to = E[t][i].first;
int di = E[t][i].second;
if(dis[to] > dis[t] + di) {
dis[to] = dis[t] + di;
q.push(make_pair(-dis[to],to));
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
动态规划
int ans = 0;
for(int i = 1; i <= n; ++i) {
scanf("%d", &num[i]);
dp[i] = 1;
for(int j = 1; j < i; ++j) {
if(num[j] <= num[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
ans = max(ans, dp[i]);
}
int binary(int x,int rr){
int l = 0,r = rr,ans;
while(l <= r){
int mid = l + r >> 1;
if(b[mid] >= x) ans = mid,r = mid - 1;
else l = mid + 1;
}
return ans;
}
int n;
for(int i = 1; i <= n;i++){
cin>>a[i];
}
int len = 1;
b[1] = a[1];
for(int i = 2;i <= n;i++){
if(a[i] > b[len]){
b[++len] = a[i];
}
else {
int t = binary(a[i],len);
b[t] = a[i];
}
}
cout<
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
for(int i = 1;i <= n;i++){
for(int j = V;j >= w[i];j--){
dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
}
}
for(int i = 0;i < n;i++){
for(int j = w[i];j <= e-s;j++){
dp[j] = min(dp[j],dp[j-w[i]]+v[i]);
}
}
for(int i = 0;i < n;i++){
for(int k = 0;k < b[i];k++){
for(int j = n;j >= v[i];j--){
dp[j] = max(dp[j],dp[j-v[i]]+w[i]);
}
}
}
#include
using namespace std;
const int N = 1e5 + 10;
int pre[N],dp[N],v[N],ans[N];
void p(int x){
if(pre[x] == 0){
cout<return;
}
p(pre[x]);
cout<<' '<int main(){
ios_base::sync_with_stdio(0);
int n,m;cin>>n>>m;
for(int i = 0;i < n;i++)cin>>v[i];
for(int i = 0;i < N;i++)pre[i] = -1,dp[i] = -INF;
sort(v,v+n);
dp[0] = 0;
for(int i = 0;i < n;i++){
for(int j = m;j >= v[i];j--){
if(dp[j] <= dp[j-v[i]]+1){
dp[j] = dp[j-v[i]]+1;
ans[j] = v[i];
pre[j] = j - v[i];
}
}
}
if(dp[m] <= 0) cout<<"No Solution";
else p(m);
cout<return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
几何
Java
import java.util.Scanner;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger[] a = new BigInteger[10100];
a[0] = BigInteger.valueOf(1);
for(int i = 1;i < 10100;i++) {
a[i] = a[i-1].multiply(BigInteger.valueOf(i));
}
Scanner in = new Scanner(System.in);
while (in.hasNextInt()) {
int x = in.nextInt();
System.out.println(a[x]);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
字符串
void getNext(string s) {
int len = s.size();
int k = -1,j = 0;
Next[0] = k;
while (j < len) {
if(k == -1 || s[k] == s[j]) {
j++,k++;
Next[j] = k;
} else k = Next[k];
}
}
void getNext(string s) {
int len = s.size();
int k = -1,j = 0;
Next[0] = k;
while (j < len) {
if(k == -1 || s[k] == s[j]) {
j++,k++;
if (s[j] == s[k]) {
Next[j] = Next[k];
} else {
Next[j] = k;
}
} else k = Next[k];
}
}
int res = 0;
int lenS = s2.size();
int j = 0,i = 0;
while (i < lenS) {
if (j == -1 || s2[i] == s1[j]) {
i++,j++;
if (j >= s1.size()) {
res++;
j = Next[j];
}
} else {
j = Next[j];
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
#include
using namespace std;
const int maxn = 1e6 + 10;
char S[maxn];
struct Trie{
int next[26];
int cnt;
void init() {
cnt = 0;
memset(next, -1, sizeof next);
}
}T[maxn];
int le;
void Insert(string s) {
int p = 0;
for (int i = 0; i < s.size(); i++) {
int r = s[i] - 'a';
if(T[p].next[r] == -1) {
T[le].init();
T[p].next[r] = le++;
}
p = T[p].next[r];
T[p].cnt++;
}
}
void query(string s) {
int p = 0;
for (int i = 0; i < s.size(); i++) {
int r = s[i] - 'a';
if(T[p].next[r] == -1) {
cout<<0<return ;
}
p = T[p].next[r];
}
cout<int main() {
ios_base::sync_with_stdio(0);
int n;cin>>n;
T[0].init();
le = 1;
for (int i = 0; i < n; i++) {
string s;cin>>s;
Insert(s);
}
int m;cin>>m;
while (m--) {
string s;cin>>s;
query(s);
}
return 0;
}