模板

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
/*
const int size = 26;//字典树节点大小
const int base = 'a';//字典树
const int maxn = 100005;//字典树大小(便于各种操作)

class tire
{
public:
	tire *next[size], *fail;
	int cnt, id;
	//各种节点设置
	tire(){ cnt = 0; fail = NULL; memset(next, 0, sizeof(next)); };
};//字典树节点设置

class Ac_machine
{
private:
	tire *root;//根节点建立
	tire *node[maxn];//与id相对立,便于各种操作
	int tot;//字典树大小
	char s[maxn];//读入字符串
	char S[maxn];//母串
public:
	Ac_machine(){}
	void clear(){ node[0] = root = new tire; tot = 0; }//初始化
	void insert(int);//插入多个字符串
	int insert();//插入字符串,返回字符串大小
	void getfail();	//获取失配指针
	int getmother();//获得匹配的母串,返回母串大小
	int work_out();//求解函数,依照题目不同而不同,返回答案
};//ac自动机设置

int Ac_machine::getmother(){ scanf("%s", S); return strlen(S); }

void Ac_machine::insert(int n){ while (n--) insert(); }

int Ac_machine::insert()
{
	scanf("%s", s);
	tire *now = root;
	for (int i = 0, k; s[i]; i++)
	{
		k = s[i] - base;
		if (!now->next[k])
		{
			node[++tot] = now->next[k] = new tire;
			now->next[k]->id = tot;
		}
		now = now->next[k];
	}
	now->cnt++;
	//可以插入一些字典树的设置
	return strlen(s);
}

void Ac_machine::getfail()
{
	queue<tire*> p;
	root->fail = root;
	for (int i = 0; i < size; i++)
	if (root->next[i])
	{
		root->next[i]->fail = root;
		p.push(root->next[i]);
	}
	else root->next[i] = root;

	tire *now;
	while (!p.empty())
	{
		now = p.front();	p.pop();
		now->cnt += now->fail->cnt;
		//可以插入统计子串个数等操作
		for (int i = 0; i < size; i++)
		if (now->next[i])
		{
			now->next[i]->fail = now->fail->next[i];
			p.push(now->next[i]);
		}
		else now->next[i] = now->fail->next[i];
	}
}

int Ac_machine::work_out()
{
	int ans = 0;
	getmother();
	getfail();
	tire *now = root;
	//for (int i = 0; i < maxn; i++) printf("%d\n", node[i]->cnt);
	for (int i = 0, k; S[i]; i++)
	{
		k = S[i] - base;
		now = now->next[k];
		ans += now->cnt;
	}
	return ans;//返回子串出现次数
}
AC自动机
*/

/*
void getnext(char *s)
{
	nt[0] = -1;  
    for (int i = 0, j; s[i]; i++)  
    {  
        j = nt[i];  
        while (j >= 0 && s[i] != s[j]) j = nt[j];  
        nt[i + 1] = j + 1;  
    }  
}
KMP算法
*/

/*
int cmp(int x, char a, char b)  
{  
    if (a > b) return x - 0;  
    if (a < b) return 1 - x;  
    return 2;  
}  
  
int present(int z,char *s)  
{  
    int i, j, k, x, y;  
    for (i = 0, j = 1, k = 0; k < n;)  
    {  
        if (i == j) { j++; k = 0; }  
        x = (i + k) % n;    y = (j + k) % n;  
        switch (cmp(z, s[x], s[y]))  
        {  
            case 0:i += k + 1; k = 0; break;  
            case 1:j += k + 1; k = 0; break;  
            case 2:k++; break;  
        }  
    }  
    return min(i, j);  
}  
最大最小表示法
present(0)代表最小
*/

/*

long long mod(long long a,long long b)
{
	return (a % b + b) % b;
}

long long inv(long long x,long long b)
{
	long long tot = 1, i = b - 2, ans = x;
	while (i)
	{
		if (i & 1) tot = mod(tot * ans,b);
		ans = mod(ans * ans,b);   i >>= 1;
	}
	return mod(tot,b);
}
欧拉定理求逆元

long long inv(long long x, long long m)
{
	if (x == 1) return x;
	return inv(m % x, m)*(m - m / x) % m;
}
x < m的逆元

void egcd(long long a, long long b, long long &x, long long &y)
{
	if (b == 0){ x = 1, y = 0; return; }
	egcd(b, a % b, x, y);

	long long t = x;
	x = y, y = t - a / b * y;
}
扩展欧几里得求逆元

求解逆元
*/

/*
const int base=1000000007;
const int size = 4;

struct Matrix
{
	int m[size][size];
	Matrix() { memset(m, 0, sizeof(m)); }

	void operator =(const Matrix&b) { memcpy(m, b.m, sizeof(m)); }

	Matrix operator *(const Matrix&b) {
		Matrix c;
		for (int i = 0; i < size;i++)
			for (int j = 0; j < size;j++)
				for (int k = 0; k < size; k++)
					c.m[i][k] = (c.m[i][k] + m[i][j] * b.m[j][k]) % base;
		return c;
	}
	Matrix get(int x)
	{
		Matrix a, b = *this;
		for (int i = 1, f = 0; x; x >>= 1)
		{
			if (x & 1)
				if (f) a = a * b; else a = b, f = 1;
			b = b * b;
		}
		return b;
	}
};
矩阵乘法
*/

/*
const int maxn=100005;
const int low(int x) { return x&-x; }
int f[maxn];

void add(int x,int y)
{
	for (int i=x;i<maxn;i+=low(i)) f[x]+=y;
}

int get(int x)
{
	int sum=0;
	for (int i=x;i;i-=low(i)) sum+=f[x];
	return sum;
}

树状数组
*/

/*

const int maxn=100005;
int f[maxn],N,n;

void add(int x, int y)
{
	x = x + N;  a[x] += y;
	for (x >>= 1; x; x >>= 1) a[x] = a[x + x] + a[x + x + 1];
}

int find(int l, int r)
{
	int tot = 0;
	for (l += N - 1, r += N + 1; l ^ r ^ 1; l >>= 1, r >>= 1)
	{
		if (~l & 1) tot += a[l ^ 1];
		if (r & 1) tot += a[r ^ 1];
	}
	return tot;
}

zkw线段树
*/

/*
struct bignum  
{  
    int len, s[maxn];  
    bignum() { memset(s, 0, sizeof(s)); len = 1; }  
    bignum operator = (const bignum &b)  
    {  
        len = b.len;  
        memcpy(s, b.s, maxn*sizeof(int));  
        return *this;  
    }  
};  
  
bignum operator +(const bignum &a, const bignum &b)  
{  
    bignum c;  
    int jw = 0, i;  
    for (i = 0; i < max(b.len, a.len) || jw>0; i++)  
    {  
        if (i < a.len) jw += a.s[i];  
        if (i < b.len) jw += b.s[i];  
        c.s[i] = jw % base;     jw /= base;  
    }  
    c.len = i;      return c;  
}  
高精度加法
*/

/*
const int maxn = 100005;
class suffix
{
private:
	char s[maxn];
	int r[maxn], rr[maxn], w[maxn], h[maxn];
	int sa[maxn], rk[maxn], n, m, rmq[maxn][20];
public:
	bool get(){
		if (scanf("%s", s + 1) != 1) return false;
		n = strlen(s + 1);
		m = 256;
		return true;
	}
	void pre()
	{
		int *x = r, *y = rr, i, j, p;

		for (i = 1; i <= m; i++) w[i] = 0;
		for (i = 1; i <= n; i++) w[x[i] = s[i]]++;
		for (i = 1; i <= m; i++) w[i] += w[i - 1];
		for (i = n; i; i--) sa[w[s[i]]--] = i;

		for (j = 1, p = 1; p < n; j += j, m = p)
		{
			for (p = 1, i = n - j + 1; i <= n; i++) y[p++] = i;
			for (i = 1; i <= n; i++) if (sa[i] > j) y[p++] = sa[i] - j;
			for (i = 0; i <= m; i++) w[i] = 0;
			for (i = 1; i <= n; i++) w[x[y[i]]]++;
			for (i = 1; i <= m; i++) w[i] += w[i - 1];
			for (i = n; i; i--) sa[w[x[y[i]]]--] = y[i];

			for (swap(x, y), p = 1, x[sa[1]] = 1, i = 2; i <= n; i++)
				x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + j] == y[sa[i - 1] + j]) ? p : ++p;
		}

		for (int i = 1; i <= n; i++) rk[sa[i]] = i;
		for (int i = 1, k = 0, j; i <= n; h[rk[i++]] = k)
		for (k ? k-- : 0, j = sa[rk[i] - 1]; s[i + k] == s[j + k]; k++);
	}
	void getrmq()
	{
		for (int i = 1; i <= n; i++) rmq[i][0] = h[i];
		for (int j = 1; (1 << j) <= n; j++)
			for (int i = 1; i + (1 << j) - 1 <= n; i++)
				rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << j - 1)][j - 1]);
	}
	void work()
	{
		int ans = 0;
		for (int i = 1; i <= n; i++)
			ans += n - sa[i] + 1 - h[i];
		printf("%d\n", ans);
	}
};
后缀数组
*/

/*
struct DLX
{
	#define maxn 500005
	#define F(i,A,s) for (int i=A[s];i!=s;i=A[i])
	int L[maxn], R[maxn], U[maxn], D[maxn];
	int row[maxn], col[maxn], ans[maxn], cnt[maxn];
	int m, num, sz;

	void add(int now, int l, int r, int u, int d, int x, int y)
	{
		L[now] = l;	R[now] = r;	U[now] = u;
		D[now] = d;   row[now] = x;  col[now] = y;
	}
	void reset(int m)//约束列的大小
	{
		num = 0x7FFFFFFF;
		this->m = m;
		for (int i = 0; i <= m; i++)
		{
			add(i, i - 1, i + 1, i, i, 0, i);
			cnt[i] = 0;
		}
		L[0] = m; 	R[m] = 0; 	sz = m + 1;
	}
	void insert(int x, int y)//按顺序插入节点
	{
		int ft = sz - 1;
		if (row[ft] != x)
		{
			add(sz, sz, sz, U[y], y, x, y);
			U[D[sz]] = sz; D[U[sz]] = sz;
		}
		else
		{
			add(sz, ft, R[ft], U[y], y, x, y);
			R[L[sz]] = sz; L[R[sz]] = sz;
			U[D[sz]] = sz; D[U[sz]] = sz;
		}
		++cnt[y];	++sz;
	}

	//精确覆盖
	void remove(int now)
	{
		R[L[now]] = R[now];
		L[R[now]] = L[now];
		F(i, D, now) F(j, R, i)
		{
			D[U[j]] = D[j];
			U[D[j]] = U[j];
			--cnt[col[j]];
		}
	}
	void resume(int now)
	{
		F(i, U, now)	F(j, L, i)
		{
			D[U[j]] = j;
			U[D[j]] = j;
			++cnt[col[j]];
		}
		R[L[now]] = now;
		L[R[now]] = now;
	}
	bool dfs(int x)
	{
		//if (x + A() >= num) return;
		if (!R[0]) { num = min(num, x); return true; }
		int now = R[0];
		F(i, R, 0) if (cnt[now]>cnt[i]) now = i;
		remove(now);
		F(i, D, now)
		{
			ans[x] = row[i];
			F(j, R, i) remove(col[j]);
			if (dfs(x + 1)) return true;
			F(j, L, i) resume(col[j]);
		}
		resume(now);
		return false;
	}
	//精确覆盖

	//重复覆盖
	void Remove(int now)
	{
		F(i, D, now)
		{
			L[R[i]] = L[i];
			R[L[i]] = R[i];
		}
	}
	void Resume(int now)
	{
		F(i, U, now) L[R[i]] = R[L[i]] = i;
	}
	int vis[maxn];
	int flag[maxn];
	int A()
	{
		int dis = 0;
		F(i, R, 0) vis[i] = 0;
		//F(i, R, 0) dis++; //求解最大值
		F(i, R, 0) if (!vis[i])
		{
			dis++;	vis[i] = 1;
			F(j, D, i) F(k, R, j) vis[col[k]] = 1;
		}
		return dis;
	}
	void Dfs(int x)
	{
		if (!R[0]) num = x;
		else if (x + A()<num)
		{
			int now = R[0];
			F(i, R, 0) if (cnt[now]>cnt[i]) now = i;
			F(i, D, now)
			//可以添加约束条件
			{
				Remove(i); F(j, R, i) Remove(j);
				Dfs(x + 1);
				F(j, L, i) Resume(j); Resume(i);
			}
		}
	}
	//重复覆盖
}dlx;

dlx模板*/

int main()
{
	
	return 0;
}

你可能感兴趣的:(模板)