[信息学]省选前模板整理

省选前把板子整理一遍,如果发现有脑抽写错的情况,欢迎各位神犇打脸 :)

数学知识

数论:

//组合数
//C(n,m) 在n个数中选m个的方案数
ll C[N][N];
void get_C(int n)
{
	for(int i=1;i<=n;i++)
	{
		C[i][i]=C[i][0]=1;
		for(int j=1;j<i;j++)
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
	}
}
//欧几里得算法
//(a,b)
ll gcd(ll a,ll b)
{
	return b==0? a:gcd(b,a%b);
}
//拓展欧几里得算法
//解同余方程 a*x+b*y = (a,b)
ll 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); }
}
//逆元
//a*inv(a,n) = 1 mod n
ll inv(ll a,ll n)
{
	ll d,x,y;
	exgcd(a,n,d,x,y);
	return d==1? (x+n)%n:-1;
}
//lucas定理
//计算较大的组合数
ll fac[N];
void get_pre(int n)
{
	for(int i=1;i<=n;i++)
		fac[i]=(fac[i-1]*i)%mod;
}
ll C(ll n,ll m,ll mod)
{
	if(n<m) return 0;
	if(n<mod&&m<mod)
		return fac[n]*inv(fac[m],mod)%mod*inv(fac[n-m],mod)%mod;
	return C(n/mod,m/mod,mod)*C(n%mod,m%mod,mod)%mod;
}
//快速幂
//a^p % mod
ll pow(ll a,ll p,ll mod)
{
	ll ans=1;
	while(p)
	{
		if(p&1) ans=(ans*a)%mod;
		a=(a*a)%mod; p>>=1;
	}
	return ans;
}
//中国剩余定理
//解线性同余方程组
//sigma{ ai*(1-ai*mi) } % M  , ai*mi+wi*y=1
ll a[N],m[N];
ll china(int n)
{
	ll M=1,d,x=0,y;
	for(int i=1;i<=n;i++) M*=m[i];
	for(int i=1;i<=n;i++)
	{
		ll w=M/m[i];
		exgcd(m[i],w,d,d,y);
		x=(x+y*w*a[i])%M;
	}
	return (x+M)%M;
}
//大步小步算法
//计算a^x=b mod n中的最小x
map<int,int> mp;
int BSGS(int a,int b,int n)
{
	int m=sqrt(n)+1,e=1,i;
	int v=inv(pow(a,m,n),n);
	mp[e]=0;
	for(i=1;i<m;i++)
	{
		e=(e*m)%n;
		if(!mp.count(e)) mp[e]=i;
	}
	for(i=0;i<m;i++)
	{
		if(mp.count(b)) return i*m+mp[b];
		b=(b*v)%mod;
	}
	return -1;
}
//快速筛法求素数表
int su[N],vis[N];
void get_su(int n)
{
	for(int i=2;i<=n;i++)
	{
		if(!vis[i]) su[++su[0]]=i;
		for(int j=1;j<=su[0]&&i*su[j]<=n;j++)
		{
			vis[i*su[j]]=1;
			if(i%su[j]==0) break;
		}
	}
}
//欧拉函数
//phi(n)小于n的数中与n互素的数的个数
ll get_phi(int n)
{
	int m=sqrt(n)+1;
	ll 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;
}
ll phi[N];
void get_phi_table(int n)
{
	phi[1]=1;
	for(int i=2;i<=n;i++) if(!phi[i])
	{
		for(int j=i;j<=n;j+=i)
		{
			if(!phi[j]) phi[j]=j;
			phi[j]=phi[j]/i*(i-1);
		}
	}
}
//莫比乌斯函数
int mu[N],su[N],vis[N];
void get_mu(int n)
{
	mu[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(!vis[i]) mu[i]=-1,su[++su[0]]=i;
		for(int j=1;j<=su[0]&&i*su[j]<=n;j++)
		{
			vis[i*su[j]]=1;
			if(i%su[j]==0) mu[i*su[j]]=0;
			else mu[i*su[j]]=-mu[i];
		}
	}
}
//高斯消元
//解线性方程组
double a[N][N];
void gause(int n)
{
	for(int i=1;i<=n;i++)
	{
		int r=i;
		for(int j=i+1;j<=n;j++)
			if(fabs(a[j][i])>fabs(a[r][i])) r=i;
		for(int j=1;j<=n+1;j++) swap(a[i][j],a[r][j]);
		for(int j=n+1;j>=i;j--)
			for(int k=i+1;k<=n;k++)
				a[k][j]-=a[k][i]/a[i][i]*a[i][j];
	}
	for(int i=n;i;i--)
	{
		for(int j=i+1;j<=n;j++)
			a[i][n+1]-=a[j][n+1]*a[i][j];
		a[i][n+1]/=a[i][i];
	}
}

高精度:

//高精度
const int maxn = 1e3+10;
const int base = 1e8;
const int wlen = 8;

int trans(char* s,int st,int ed)
{
	int x=0;
	for(int i=st;i<ed;i++) x=x*10+s[i]-‘0‘;
	return x;
}

struct Bign
{
	int len; ll N[maxn];
	Bign() { len=1; memset(N,0,sizeof(N)); }
	Bign(ll num) {  *this=num; }
	Bign(const char* s) { *this=s; }
	void print()
	{
		printf("%d",N[len-1]);
		for(int i=len-2;i>=0;i--)
			printf("%08d",N[i]);
		puts("");
	}
	Bign operator = (const ll x)
	{
		ll num=x;
		while(num>base)
		{
			N[len++]=num%base;
			num/=base;
		}
		N[len++]=num;
		return *this;
	}
	Bign operator = (char* s)
	{
		int L=strlen(s);
		len=(L-1)/wlen+1;
		for(int i=0;i<len;i++)
		{
			int ed=L-i*wlen;
			int st=max(0,ed-wlen);
			N[i]=trans(s,st,ed);
		}
		return *this;
	}
	bool operator < (const Bign& B) const
	{
		if(len!=B.len) return len<B.len;
		for(int i=len-1;i>=0;i--)
			if(N[i]!=B.N[i]) return N[i]<B.N[i];
		return 0;
	}
	bool operator <= (const Bign& B) const
	{
		return !(B<(*this));
	}

	void clear()
	{
		while(len>1&&N[len-1]==0) len--;
	}

	Bign operator + (const Bign& B) const
	{
		Bign C;
		C.len=max(len,B.len)+10;
		for(int i=0;i<C.len;i++)
		{
			C.N[i]+=N[i]+B.N[i];
			C.N[i+1]+=C.N[i]/base;
			C.N[i]%=base;
		}
		C.clear();
		return C;
	}
	Bign operator - (Bign B)
	{
		Bign C;
		C.len=max(len,B.len);
		for(int i=0;i<C.len;i++)
		{
			if(N[i]<B.N[i]) {
				N[i+1]--;
				N[i]+=base;
			}
			C.N[i]=N[i]-B.N[i];
		}
		C.clear();
		return C;
	}
	Bign operator * (const Bign& B) const
	{
		Bign C;
		C.len=len+B.len;
		for(int i=0;i<len;i++)
			for(int j=0;j<B.len;j++)
				C.N[i+j]+=N[i]*B.N[j];
		for(int i=0;i<C.len;i++)
		{
			C.N[i+1]+=C.N[i]/base;
			C.N[i]%=base;
		}
		C.clear();
		return C;
	}
	Bign operator / (const Bign& B)
	{
		Bign C,F;
		C.len=len;
		for(int i=len-1;i>=0;i--)
		{
			F=F*base;
			F.N[0]=N[i];
			while(B<=F)
			{
				F=F-B;
				C.N[i]++;
			}
		}
		C.clear();
		return C;
	}
	Bign operator % (const Bign& B)
	{
		Bign r=*this/B;
		return *this-r*B;
	}

}A,B;

矩阵乘法:

//矩阵乘法
struct Mat
{
	int r,c; ll N[maxn][maxn];
	Mat(int r=0,int c=0)
	{
		this->r=r,this->c=c;
		memset(N,0,sizeof(N));
	}
	Mat operator * (const Mat& B) const
	{
		Mat C(r,B.c);
		for(int i=0;i<r;i++)
			for(int j=0;j<B.c;j++)
				for(int k=0;k<c;k++)
					C.N[i][j]=(C.N[i][j]+N[i][k]*B.N[k][j])%mod;
		return C;
	}
	Mat operator ^ (int p)
	{
		Mat ans(r,r),tmp=*this;
		for(int i=0;i<r;i++) ans.N[i][i]=1;
		while(p)
		{
			if(p&1) ans=ans*tmp;
			tmp=tmp*tmp; p>>=1;
		}
		return ans;
	}

};

 

数据结构

树状数组:

//树状数组
int C[N],mx;
void Add(int x,int v)
{
    for(int i=x;i<=mx;i+=i&-i) C[i]+=v;
}
int query(int x)
{
    int ans=0;
    for(int i=x;i;i-=i&-i) ans+=C[i];
    return ans;
}

  

线段树:

//线段树
//区间加,区间乘,区间求和
int mod;
struct Tnode
{
	int u,l,r;
	ll sum,add,mul;
	void mulv(ll x) {
		sum=(sum*x)%mod;
		mul=(mul*x)%mod;
		add=(add*x)%mod;
	}
	void addv(ll x) {
		sum=(sum+(r-l+1)*x%mod)%mod;
		add=(add+x)%mod;
	}
	void pushdown() ;
	void maintain() ;
}T[N];
void Tnode::pushdown() {
	if(mul^1) {
		T[u<<1].mulv(mul);
		T[u<<1|1].mulv(mul);
		mul=1;
	}
	if(add) {
		T[u<<1].addv(add);
		T[u<<1|1].addv(add);
		add=0;
	}
}
void Tnode::maintain() {
	sum=(T[u<<1].sum+T[u<<1|1].sum)%mod;
}

void update(int u,int L,int R,int x,int f)
{
	T[u].pushdown();
	if(L<=T[u].l&&T[u].r<=R) {
		if(!f) T[u].addv(x);
		else T[u].mulv(x);
	} else {
		int mid=T[u].l+T[u].r>>1;
		if(L<=mid) update(u<<1,L,R,x,f);
		if(mid<R) update(u<<1|1,L,R,x,f);
		T[u].maintain();
	}
}
ll query(int u,int L,int R)
{
	T[u].pushdown();
	if(L<=T[u].l&&T[u].r<=R)
		return T[u].sum;
	else {
		int mid=T[u].l+T[u].r>>1;
		ll ans=0;
		if(L<=mid) ans=(ans+query(u<<1,L,R))%mod;
		if(mid<R) ans=(ans+query(u<<1|1,L,R))%mod;
		return ans;
	}
}
ll a[N];

void build(int u,int l,int r)
{
	T[u]=(Tnode){ u,l,r,0,0,1 };
	if(l==r) {
		T[u].sum=a[l];
	} else {
		int mid=l+r>>1;
		build(u<<1,l,mid);
		build(u<<1|1,mid+1,r);
		T[u].maintain();
	}
}

Treap:

//Treap
struct Node
{
	Node *ch[2];
	int v,r,m,w,s;
	Node(int v):v(v) { ch[0]=ch[1]=NULL; r=rand(); s=w=1; }
	int cmp(int x) {
		if(v==x) return -1;
		return x<v? 0:1;
	}
	void maintain() {
		s=w;
		if(ch[0]!=NULL) s+=ch[0]->s;
		if(ch[1]!=NULL) s+=ch[1]->s;
	}
};

void rotate(Node* &o,int d)
{
	Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
	o->maintain(); k->maintain(); o=k;
}
void insert(Node *&o,int x)
{
	if(o==NULL) o=new Node(x);
	int d=o->cmp(x);
	if(d==-1) o->w++;
	else {
		insert(o->ch[d],x);
		if(o->ch[d]->r > o->r) rotate(o,d^1);
	}
	o->maintain();
}
void remove(Node *&o,int x)
{
	int d=o->cmp(x);
	if(d==-1)
	{
		if(o->s>1) { o->w--; o->maintain(); return ; }
		else {
			if(o->ch[0]!=NULL&&o->ch[1]!=NULL) {
				int d2=o->ch[0]->r > o->ch[1]->r ? 1:0;
				rotate(o,d2); remove(o->ch[d2],x);
			} else {
				if(o->ch[0]!=NULL) o=o->ch[0]; else o=o->ch[1];
				delete o;
			}
		}
	} else
		remove(o->ch[d],x);
	if(o!=NULL) o->maintain();
}
int kth(Node* o,int rk)
{
	if(o==NULL) return 0;
	int s=o->ch[0]==NULL? 0:o->ch[0]->s;
	if(rk==s+1) return o->v;
	else if(rk<=s) return kth(o->ch[0],rk);
	else return kth(o->ch[1],rk-s-o->w);
}
int rank(Node* o,int x)
{
	if(o==NULL) return 0;
	int s=o->ch[0]==NULL? 0:o->ch[0]->s;
	int d=o->cmp(x);
	if(d==-1) return 1;
	else if(d==0) return rank(o->ch[0],x);
	else return s+o->w+rank(o->ch[1],x);
}
int tmp;
void before(Node* o,int x)
{
	if(o==NULL) return ;
	if(o->v<x) { tmp=max(tmp,o->v); before(o->ch[1],x); }
	else before(o->ch[0],x);
}
void after(Node* o,int x)
{
	if(o==NULL) return ;
	if(o->v>x) { tmp=min(tmp,o->v); after(o->ch[0],x); }
	else after(o->ch[1],x);
}

splay:

//splay自上而下
struct Node
{
	Node *ch[2];
	int s;
	int cmp(int x)
	{
		int d=x-ch[0]->s;
		if(d==1) return -1;
		return d<=0? 0:1;
	}
	void maintain()
	{
		s=ch[0]->s+ch[1]->s;
	}
	void pushdown() {}
}mempool[N],*G=mempool;

Node* null=new Node();
void rotate(Node* &o,int d)
{
	Node* k=o->ch[d^1]; o->ch[d^1]=k->ch[d],k->ch[d]=o;
	o->maintain(); k->maintain(); o=k;
}
void splay(Node* &o,int k)
{
	o->pushdown();
	int d=o->cmp(k);
	if(d==1) k-=o->ch[0]->s+1;
	if(d!=-1) {
		Node* p=o->ch[d];
		p->pushdown();
		int d2=p->cmp(k),k2=d2==0? k:k-p->ch[d]->s-1;
		if(d2!=-1) {
			splay(p->ch[d2],k2);
			if(d==d2) rotate(o,d^1); else rotate(o->ch[d],d);
		}
		rotate(o,d^1);
	}
}
Node* merge(Node* left,Node* right)
{
	splay(left,left->s);
	left->ch[1]=right,left->maintain();
	return left;
}
void split(Node* o,int k,Node*&left,Node*&right)
{
	splay(o,k);
	left=o,right=left->ch[1],left->ch[1]=NULL;
	left->maintain();
}
Node* build(int l,int r)
{
	if(r<l) return null;
	int mid=l+r>>1;
	G->s=1;
	G->ch[0]=build(l,mid-1);
	G->ch[1]=build(mid+1,r);
	G->maintain();
	return G++;
}

主席树:

//主席树
struct Tnode
{
	Tnode *ls,*rs;
	int sum;
} *T[N*50],mempool[N*50],*G=mempool;

Tnode* Nw(Tnode* l,Tnode* r,int x)
{
	G->ls=l,G->rs=r,G->sum=x;
	return G++;
}
Tnode* build(Tnode* p,int l,int r,int pos)
{
	if(l==r)
		return Nw(T[0],T[0],p->sum+1);
	else {
		int mid=l+r>>1;
		if(pos<=mid) Nw(build(p->ls,l,mid,pos),p->rs,p->sum+1);
		else return Nw(p->ls,build(p->rs,mid+1,r,pos),p->sum+1);
	}
}
int query(Tnode* x,int l,int r,int pos)
{
	if(l==r) return x->sum;
	else {
		int mid=l+r>>1;
		if(pos<=mid) return query(x->ls,l,mid,pos);
		else return query(x->rs,mid+1,r,pos);
	}
}

Link-Cut-Tree

//Link-Cut-Tree
namespace LCT
{

	struct Node {
		Node *ch[2],*fa;
		int rev;
		//others v
		Node() {};
		Node(int x) ;
		void reverse() {
			swap(ch[0],ch[1]);
			rev^=1;
		}
		void up_push() {
			if(fa->ch[0]==this||fa->ch[1]==this)
				fa->up_push();
			if(rev) {
				ch[0]->reverse();
				ch[1]->reverse();
				rev=0;
			}
		}
		void maintain() { }
	} T[N<<1],*null=&T[0];
	Node::Node(int x) {
		ch[0]=ch[1]=fa=null;
		rev=0; //v=x;
	}
	void rot(Node* o,int d) {
		Node* p=o->fa;
		p->ch[d]=o->ch[d^1];
		o->ch[d^1]->fa=p;
		o->ch[d^1]=p;
		o->fa=p->fa;
		if(p==p->fa->ch[0])
			p->fa->ch[0]=o;
		else if(p==p->fa->ch[1])
			p->fa->ch[1]=o;
		p->fa=o;
		p->maintain();
	}
	void splay(Node* o) {
		o->up_push();
		Node *nf,*nff;
		while(o->fa->ch[0]==o||o->fa->ch[1]==o) {
			nf=o->fa,nff=nf->fa;
			if(o==nf->ch[0]) {
				if(nf==nff->ch[0]) rot(nf,0);
				rot(o,0);
			} else {
				if(nf==nff->ch[1]) rot(nf,1);
				rot(o,1);
			}
		}
		o->maintain();
	}
	void Access(Node* o) {
		Node *son=null;
		while(o!=null) {
			splay(o);
			o->ch[1]=son;
			o->maintain();
			son=o; o=o->fa;
		}
	}
	void evert(Node* o) {
		Access(o);
		splay(o);
		o->reverse();
	}
	void Link(Node* u,Node* v) {
		evert(u);
		u->fa=v;
	}
	void Cut(Node* u,Node* v) {
		evert(u);
		Access(v),splay(v);
		v->ch[0]=u->fa=null;
		v->maintain();
	}
	Node* find(Node* o) {
		while(o->fa!=null) o=o->fa;
		return o;
	}

}
using namespace LCT ;

2-SAT:

//2-sat
struct TwoSAT {
	int n;
	vector<int> g[N<<1];
	int st[N<<1],mark[N<<1],top;

	bool dfs(int x) {
		if(mark[x^1]) return 0;
		if(mark[x]) return 1;
		mark[x]=1;
		st[++top]=x;
		for(int i=0;i<g[x].size();i++)
			if(!dfs(g[x][i])) return 0;
		return 1;
	}
	void init(int n) {
		this->n=n;
		for(int i=0;i<2*n;i++) g[i].clear();
		memset(mark,0,sizeof(mark));
	}
	void addc(int x,int xval,int y,int yval) {
		x=x*2+xval;
		y=y*2+yval;
		g[x^1].push_back(y);
		g[y^1].push_back(x);
	}
	bool solve() {
		for(int i=0;i<2*n;i+=2) {
			if(!mark[i]&&!mark[i+1]) {
				top=0;
				if(!dfs(i)) {
					while(top) mark[st[top--]]=0;
					if(!dfs(i+1)) return 0;
				}
			}
		}
		return 1;
	}

} s;

  

有向图的强联通分量:

//tarjan求SCC
struct Edge {
	int v,nxt;
}e[M];
int en=1,front[N];
void adde(int u,int v)
{
	e[++en]=(Edge){v,front[u]}; front[u]=en;
}

int n,top,dfn;
int st[N],sccno[N],scc_cnt,pre[N],lowlink[N];

void tarjan(int u)
{
	pre[u]=lowlink[u]=++dfn;
	st[++top]=u;
	trav(u,i) {
		int v=e[i].v;
		if(!pre[v]) {
			tarjan(v);
			lowlink[u]=min(lowlink[u],lowlink[v]);
		} else
		if(!sccno[v])
			lowlink[u]=min(lowlink[u],pre[v]);
	}
	if(lowlink[u]==pre[u]) {
		scc_cnt++;
		for(;;) {
			int x=st[top--];
			sccno[x]=scc_cnt;
			if(x==u) break;
		}
	}
}

无向图的边的双连通分量:

//BCC
struct Edge {
	int u,v,nxt;
}e[M];
int en=1,front[N];
void adde(int u,int v)
{
	e[++en]=(Edge){u,v,front[u]}; front[u]=en;
}

Edge st[N];
vector<int> bcc[N];
int pre[N],iscut[N],bccno[N],top,dfn,bcc_cnt;

int dfs(int u,int fa)
{
	int lowu=pre[u]=++dfn;
	int child=0;
	trav(u,i) {
		int v=e[i].v;
		Edge E=e[i];
		if(!pre[v]) {
			st[++top]=E;
			child++;
			int lowv=dfs(v,u);
			lowu=min(lowu,lowv);
			if(lowv>=pre[u]) {
				iscut[u]=1;
				bcc_cnt++;
				for(;;) {
					Edge x=st[top--];
					if(bccno[x.u]!=bcc_cnt) {
						bccno[x.u]=bcc_cnt;
						bcc[bcc_cnt].push_back(x.u);
					}
					if(bccno[x.v]!=bcc_cnt) {
						bccno[x.v]=bcc_cnt;
						bcc[bcc_cnt].push_back(x.v);
					}
					if(x.u==u&&x.v==v) break;
				}
			}
		} else
		if(pre[v]<pre[u] && v!=fa) {
			st[++top]=E;
			lowu=min(lowu,pre[v]);
		}
	}
	if(fa<0&&child==1) iscut[u]=0;
	return lowu;
}

  

最短路:

//spfa

struct Edge {
	int v,w,nxt;
}e[M];
int en=1,front[N];
void adde(int u,int v,int w)
{
	e[++en]=(Edge){v,w,front[u]}; front[u]=en;
}

queue<int> q;
int inq[N],dis[N];
void spfa(int s)
{
	dis[s]=0; inq[s]=1;
	q.push(s);
	while(!q.empty()) {
		int u=q.front(); q.pop();
		inq[u]=0;
		trav(u,i) {
			int v=e[i].v;
			if(dis[v]>dis[u]+e[i].w) {
				dis[v]=dis[u]+e[i].w;
				if(!inq[v]) {
					inq[v]=1;
					q.push(v);
				}
			}
		}
	}
}

//dijkstra

struct Node {
	int id,dis;
	bool operator < (const Node& rhs) const
	{
		return dis>rhs.dis;
	}
};
priority_queue<Node> q;

int vis[N],dis[N];
void dijkstra(int s)
{
	q.push((Node){s,0});
	while(!q.empty()) {
		int u=q.top().id;
		if(vis[u]) continue;
		vis[u]=1;
		trav(u,i) {
			int v=e[i].v;
			if(dis[v]>dis[u]+e[i].w) {
				dis[v]=dis[u]+e[i].w;
				q.push((Node){v,dis[v]});
			}
		}
	}
}

  

最小生成树:

//Kruskal 

int fa[N];
int find(int u)
{
	if(!fa[u] || u==fa[u]) return fa[u]=u;
	return fa[u]=find(fa[u]);
}

struct Edge {
	int u,v,w;
	bool operator < (const Edge& rhs) const
	{
		return w<rhs.w;
	}
}e[M];
int tot;

void Kruskal()
{
	sort(e+1,e+tot+1);
	for(int i=1;i<=tot;i++) {
		int u=e[i].u,v=e[i].v;
		int x=find(u),y=find(v);
		if(x!=y) {
			fa[x]=y;
			//加入树边(u,v)
		}
	}
}

  

最大流:

//Dinic算法求最大流
struct Edge {
	int u,v,cap,flow;
};
struct Dinic {
	int d[N],cur[N],vis[N];
	vector<Edge> es;
	vector<int> g[N];
	queue<int> q;

	void AddEdge (int u,int v,int w) {
		es.push_back((Edge){u,v,w,0});
		es.push_back((Edge){v,u,0,0});
		int m=es.size();
		g[u].push_back(m-2);
		g[v].push_back(m-1);
	}
	bool bfs(int s,int t) {
		memset(vis,0,sizeof(vis));
		d[s]=0; vis[s]=1;
		q.push(s);
		while(!q.empty()) {
			int u=q.front(); q.pop();
			FOR(i,0,(int)g[u].size()-1) {
				Edge& e=es[g[u][i]];
				int v=e.v;
				if(e.cap>e.flow&&!vis[v]) {
					vis[v]=1;
					d[v]=d[u]+1;
					q.push(v);
				}
			}
		}
		return vis[t];
	}
	int dfs(int u,int a,int t) {
		if(u==t||a==0) return a;
		int flow=0,f;
		for(int& i=cur[u];i<g[u].size();i++) {
			Edge& e=es[g[u][i]];
			int v=e.v;
			if(d[v]==d[u]+1&&(f=dfs(v,min(a,e.cap-e.flow),t))>0) {
				e.flow+=f;
				es[g[u][i]^1].flow-=f;
				flow+=f,a-=f;
				if(!a) break;
			}
		}
		return flow;
	}
	int maxflow(int s,int t) {
		int flow=0;
		while(bfs(s,t)) {
			memset(cur,0,sizeof(cur));
			flow+=dfs(s,inf,t);
		}
		return flow;
	}
} dc;

  

最小费用最大流:

/最短路算法求最小费用最大流
struct Edge {
	int u,v,cap,flow,cost;
	Edge(int _,int __,int ___,int ____,int _____)
	{ u=_,v=__,cap=___,flow=____,cost=_____; }
};

struct MCMF {
	int n,m,s,t;
	int d[N],p[N],a[N],inq[N];
	vector<Edge> es;
	vector<int> g[N];
	queue<int> q;
	void init(int n) {
		this->n=n;
		es.clear();
		for(int i=0;i<=n;i++) g[i].clear();
	}
	void AddEdge(int u,int v,int w,int c) {
		es.push_back(Edge(u,v,w,0,c));
		es.push_back(Edge(v,u,0,0,-c));
		int m=es.size();
		g[u].push_back(m-2);
		g[v].push_back(m-1);
	}
	bool spfa(int s,int t,ll& flow,ll& cost) {
		memset(inq,0,sizeof(inq));
		for(int i=0;i<=n;i++) d[i]=inf;
		inq[s]=1; d[s]=p[s]=0; a[s]=inf;
		q.push(s);
		while(!q.empty()) {
			int u=q.front(); q.pop();
			inq[u]=0;
			for(int i=0;i<g[u].size();i++) {
				Edge& e=es[g[u][i]];
				int v=e.v;
				if(d[v]>d[u]+e.cost && e.cap>e.flow) {
					d[v]=d[u]+e.cost;
					a[v]=min(a[u],e.cap-e.flow);
					p[v]=g[u][i];
					if(!inq[v])
						inq[v]=1 , q.push(v);
				}
			}
		}
		if(d[t]==inf) return 0;
		flow+=a[t],cost+=a[t]*d[t];
		for(int x=t;x!=s;x=es[p[x]].u) {
			es[p[x]].flow+=a[t];
			es[p[x]^1].flow-=a[t];
		}
		return 1;
	}
	void mcmf(int s,int t,ll& cost,ll& flow) {
		flow=cost=0;
		while(spfa(s,t,cost,flow)) ;
	}
} mc;

 

KM算法:

//KM算法求二分图的最佳完美匹配
struct KM {
	int slack[N],res[N];
	int l[N],r[N],lx[N],rx[N],g[N][N];

	void clear(int n) {
		for(int i=1;i<=n;i++) {
			res[i]=0;
			for(int j=1;j<=n;j++) g[i][j]=-1;
		}
	}
	bool find(int x,int n) {
		lx[x]=1;
		for(int i=1;i<=n;i++)
			if(!rx[i]&&g[x][i]!=-1) {
				int tmp=g[x][i]-l[x]-r[i];
				if(!tmp) {
					rx[i]=1;
					if(!res[i]||find(res[i],n)) {
						res[i]=x;
						return 1;
					}
				} else
					slack[i]=min(slack[i],tmp);
			}
		return 0;
	}
	int solve(int n) {
		if(!n) return 0;
		for(int i=1;i<=n;i++) r[i]=0;
		for(int i=1;i<=n;i++) {
			l[i]=INF;
			for(int j=1;j<=n;j++) if(g[i][j]!=-1)
				l[i]=min(l[i],g[i][j]);
		}
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=n;j++) slack[j]=INF;
			for(;;) {
				for(int j=1;j<=n;j++) lx[j]=rx[j]=0;
				if(find(i,n)) break;
				int mini=INF;
				for(int i=1;i<=n;i++) if(!rx[i])
					mini=min(mini,slack[i]);
				for(int i=1;i<=n;i++) {
					if(lx[i]) l[i]+=mini;
					if(rx[i]) r[i]-=mini;
					else slack[i]-=mini;
				}
			}
		}
		int ans=0;
		for(int i=1;i<=n;i++)
			ans+=l[i]+r[i];
		return ans;
	}
} km;

  

 

LCA:

//倍增法求LCA
//倍增法可以在线构造 比较灵活
struct Edge {
	int v,nxt;
}e[M];
int en=1,front[N];
void adde(int u,int v)
{
	e[++en]=(Edge){v,front[u]}; front[u]=en;
}

int fa[N][D],dep[N];

void dfs(int u)
{
	for(int i=1;i<D;i++)
		fa[u][i]=fa[fa[u][i-1]][i-1];
	trav(u,i) {
		int v=e[i].v;
		if(v!=fa[u][0]) {
			fa[v][0]=u;
			dep[v]=dep[u]+1;
			dfs(v);
		}
	}
}
int lca(int u,int v)
{
	if(dep[u]<dep[v]) swap(u,v);
	int t=dep[u]-dep[v];
	for(int i=0;i<D;i++)
		if(t&(1<<i)) u=fa[u][i];
	if(u==v) return u;
	for(int i=D-1;i>=0;i--)
		if(fa[u][i]!=fa[v][i])
			u=fa[u][i],v=fa[v][i];
	return fa[u][0];
}

//树链剖分求LCA
//比较快
struct Edge {
	int v,nxt;
}e[M];
int en=1,front[N];
void adde(int u,int v)
{
	e[++en]=(Edge){v,front[u]}; front[u]=en;
}

int fa[N],top[N],siz[N],dep[N],son[N];
void dfs1(int u)
{
	siz[u]=1; son[u]=0;
	trav(u,i) {
		int v=e[i].v;
		if(v!=fa[u]) {
			fa[v]=u;
			dep[v]=dep[u]+1;
			dfs1(v);
			siz[u]+=siz[v];
			if(siz[v]>siz[son[u]]) son[u]=v;
		}
	}
}
void dfs2(int u,int tp)
{
	top[u]=tp;
	if(son[u]) dfs2(son[u],tp);
	trav(u,i)
		if(e[i].v!=fa[u]&&e[i].v!=son[u])
			dfs2(e[i].v,e[i].v);
}
int lca(int u,int v)
{
	while(top[u]!=top[v]) {
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		u=fa[top[u]];
	}
	return dep[u]<dep[v]? u:v;
}

  

树链剖分:

//树链剖分
struct Edge {
	int v,nxt;
}e[M];
int en=1,front[N];
void adde(int u,int v)
{
	e[++en]=(Edge){v,front[u]}; front[u]=en;
}

int fa[N],top[N],siz[N],dep[N],son[N],bl[N],dfn;
void dfs1(int u)
{
	siz[u]=1; son[u]=0;
	trav(u,i) {
		int v=e[i].v;
		if(v!=fa[u]) {
			fa[v]=u;
			dep[v]=dep[u]+1;
			dfs1(v);
			siz[u]+=siz[v];
			if(siz[v]>siz[son[u]]) son[u]=v;
		}
	}
}
void dfs2(int u,int tp)
{
	top[u]=tp; bl[u]=++dfn;
	if(son[u]) dfs2(son[u],tp);
	trav(u,i)
		if(e[i].v!=fa[u]&&e[i].v!=son[u])
			dfs2(e[i].v,e[i].v);
}
//以合适的数据结构T维护重链
int ans;
int query(int u,int v)
{
	while(top[u]!=top[v]) {
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		ans<-query(T,bl[top[u]],bl[u]);
		u=fa[top[u]];
	}
	if(u==v) return ;
	if(dep[u]>dep[v]) swap(u,v);
	ans<-query(T,bl[u],bl[v]);
	<-ans
}
//类似-查询树上任意两节点的方法
void modify() {}

  

点分治:

//点分治
struct Edge {
	int v,nxt;
}e[M];
int en=1,front[N];
void adde(int u,int v)
{
	e[++en]=(Edge){v,front[u]}; front[u]=en;
}

int rt,n,size,vis[N],siz[N],f[N],dep[N];

void get_root(int u,int fa)
{
	siz[u]=1; f[u]=0;
	trav(u,i) {
		int v=e[i].v;
		if(v!=fa) {
			get_root(v,u);
			siz[u]+=siz[v];
			if(siz[v]>f[u]) f[u]=siz[v];
		}
	}
	f[u]=max(f[u],size-siz[u]);
	if(f[u]<f[rt]) rt=u;
}
void solve(int u)
{
	vis[u]=1;
	//计算经过根u的信息
	trav(u,i) if(!vis[e[i].v])
	{
		//统计当前子树信息
		//与前i-1个子树信息结合计算贡献
		//将当前子树信息加入前i-1个子树信息
	}
	trav(u,i) if(!vis[e[i].v]) {
		int v=e[i].v;
		size=siz[v]; rt=0;
		get_root(v,-1);
		solve(rt);
	}
}
int main()
{
	//blabla
	size=f[0]=n;
	rt=0; get_root(rt,-1);
	solve(rt);
}

  

字符串

KMP:

//KMP算法
//s[s]==s[fail[i]] , fail[i]!=0
int f[N]; char s[N];
void get_fail()
{
	int j=0;
	int n=strlen(s);
	for(int i=2;i<n;i++) {
		while(j&&s[j+1]!=s[i]) j=f[j];
		if(s[j+1]==s[i]) j++;
		f[i]=j;
	}
}

  

AC自动机:

//AC自动机
struct AC_auto {
	int sz,ch[N][26],f[N],val[N];
	AC_auto() {
		sz=1;
		memset(ch,0,sizeof(ch));
	}
	void insert(char* s) {
		int u=0;
		for(int i=0;s[i];i++) {
			int c=s[i]-‘a‘;
			if(!ch[u][c]) ch[u][c]=++sz;
			u=ch[u][c];
		}
		val[u]=1;
	}
	void get_fail() {
		queue<int> q;
		f[0]=0;
		for(int c=0;c<26;c++)
			if(ch[0][c]) f[ch[0][c]]=0,q.push(ch[0][c]);
		while(!q.empty()) {
			int qr=q.front(); q.pop();
			for(int c=0;c<26;c++) {
				int u=ch[qr][c];
				if(!u) continue;
				q.push(u);
				int v=f[qr];
				while(v&&!ch[v][c]) v=f[v];
				if(val[ch[v][c]]) val[u]=1;
				f[u]=ch[v][c];
			}
		}
	}
};

  

  

后缀自动机:

//后缀自动机SAM
struct SAM {
	int sz,last,fa[N],ch[N][26],l[N];
	SAM() {
		sz=0; last=++sz;
		memset(l,0,sizeof(l));
		memset(fa,0,sizeof(fa));
	}
	void Add(int c) {
		int np=++sz,p=last; last=np;
		l[np]=l[p]+1;
		for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
		if(!p) fa[np]=1;
		else {
			int q=ch[p][c];
			if(l[q]==l[p]+1) fa[np]=q;
			else {
				int nq=++sz; l[nq]=l[p]+1;
				memcpy(ch[nq],ch[q],sizeof(ch[q]));
				fa[nq]=fa[q];
				fa[q]=fa[np]=nq;
				for(;q==ch[p][c];p=fa[p]) ch[p][c]=nq;
			}
		}
	}
	//do some other things

} sam;

  

后缀数组:

//后缀数组
#define rep(a,b,c) for(int a=(b);a>=(c);a--)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
char s[N];
int c[N],t[N],t2[N],height[N],rank[N],sa[N];
void build_sa(int m,int n) {
	int *x=t,*y=t2,p,k;
	FOR(i,0,m-1) c[i]=0;
	FOR(i,0,n-1) c[x[i]=s[i]]++;
	FOR(i,0,m-1) c[i]+=c[i-1];
	rep(i,n-1,0) sa[--c[x[i]]]=i;

	for(k=1;k<=n;k<<=1) {
		p=0;
		FOR(i,n-k,n-1) y[p++]=i;
		FOR(i,0,n-1) if(sa[i]>=k) y[p++]=sa[i]-k;

		FOR(i,0,m-1) c[i]=0;
		FOR(i,0,n-1) c[x[y[i]]]++;
		FOR(i,0,m-1) c[i]+=c[i-1];
		rep(i,n-1,0) sa[--c[x[y[i]]]]=y[i];

		swap(x,y);
		p=1; x[sa[0]]=0;
		FOR(i,1,n-1)
			x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]? p-1:p++;
		if(p>=n) break;
		m=p;
	}
}
void get_height(int n)
{
	FOR(i,0,n-1) rank[sa[i]]=i;
	int k=0;
	FOR(i,0,n-1) {
		if(k) k--;
		int j=sa[rank[i]-1];
		while(s[i+k]==s[j+k]) k++;
		height[rank[i]]=k;
	}
}

  

Manacher:

//Manacher算法
char s[N],a[N];
int p[N];
void Add(int l,int r)
{
	l=l/2,r=r/2-1;
	if(l>r) return ;
	//q[++tot]=(Seg){l,r};
	//[l,r]为一个回文串
}
void Manacher()
{
	int n=strlen(s+1);
	int m=n*2+1;
	for(int i=1;i<=n;i++) {
		a[i<<1]=s[i];
		a[i<<1|1]=‘#‘;
	}
	a[0]=‘+‘,a[1]=‘#‘,a[m+1]=‘-‘;
	int mx=0,id;
	for(int i=1;i<=m;i++) {
		if(mx>i) p[i]=min(mx-i,p[id*2-i]);
		else p[i]=1;
		while(a[i-p[i]]==a[i+p[i]]) p[i]++;
		Add(i-p[i],i+p[i]);
		if(p[i]+i>mx) mx=i+p[i],id=i;
	}
}

  

计算几何

计算几何基础知识:

//计算几何基础

const double eps = 1e-10;
int dcmp(double x) {
	if(fabs(x)<eps) return 0; else return x<0? -1:1;
}

struct Pt {
	double x,y;
	Pt(double x=0,double y=0):x(x),y(y) {}
};
typedef Pt vec;

vec operator - (Pt A,Pt B) { return vec(A.x-B.x,A.y-B.y); }
vec operator + (vec A,vec B) { return vec(A.x+B.x,A.y+B.y); }
vec operator * (vec A,double p) { return vec(A.x*p , A.y*p); }
bool operator < (const Pt& a,const Pt& b) {
	return a.x<b.x || (a.x==b.x && a.y<b.y);
}
bool operator == (const Pt& a,const Pt& b) {
	return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;
}

double cross(vec A,vec B) { return A.x*B.y-A.y*B.x; }
double Dot(vec A,vec B) { return A.x*B.x+A.y*B.y; }
double Len(vec A) { return sqrt(Dot(A,A)); }
double Angle(vec A,vec B) { return acos(Dot(A,B)/Len(A)/Len(B)); }

//逆时针旋转rad角度
vec rotate(vec A,double rad) {
	return vec(A.x*cos(rad)-A.y*sin(rad) , A.x*sin(rad)+A.y*cos(rad));
}
//法向量 左转90度 长度归1
vec Normal(vec A)
{
	double L=Len(A);
	return vec(-A.y/L,A.x/L);
}
//判断点在线段上
bool OnSeg(Pt P,Pt a1,Pt a2) {
	return dcmp(cross(a1-P,a2-P))==0 && dcmp(Dot(a1-P,a2-P))<0;
}
//直线交点
Pt LineIntersection(Pt P,vec v,Pt Q,vec w) {
	vec u=P-Q;
	double t=cross(w,u)/cross(v,w);
	return P+v*t;
}
double DistoLine(Pt P,Pt A,Pt B) {
	vec v1=B-A,v2=P-A;
	return fabs(cross(v1,v2))/Len(v1);
}
//线段不含端点 判断相交
bool SegIntersection(Pt a1,Pt a2,Pt b1,Pt b2) {
	double c1=cross(a2-a1,b1-a1) , c2=cross(a2-a1,b2-a1) ,
		   c3=cross(b2-b1,a1-b1) , c4=cross(b2-b1,a2-b1);
	return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
	// b1 b2在线段a1a2的两侧  a1 a2在线段b1b2的两侧  规范相交
}
//线段含端点 判断线段严格相交
bool SegInter(Pt s1, Pt e1, Pt s2, Pt e2) {
    if( min(s1.x, e1.x) <= max(s2.x, e2.x) &&
        min(s1.y, e1.y) <= max(s2.y, e2.y) &&
        min(s2.x, e2.x) <= max(s1.x, e1.x) &&
        min(s2.y, e2.y) <= max(s1.y, e1.y) &&
        cross(e1-s1,s2-s1) * cross(e1-s1,e2-s1) <= 0 &&
        cross(e2-s2,s1-s2) * cross(e2-s2,e1-s2) <= 0
	  ) return true;
    return false;
}
//点到线段的距离
double DistoSeg(Pt P,Pt A,Pt B) {
	if(A==B) return Len(P-A);
	vec v1=B-A , v2=P-A , v3=P-B;
	if(dcmp(Dot(v1,v2))<0) return Len(v2);
	else if(dcmp(Dot(v1,v3))>0) return Len(v3);
	else return fabs(cross(v1,v2))/Len(v1);
}
//多边形面积
double PolygonArea(Pt* p,int n)
{
	double S=0;
	for(int i=1;i<n-1;i++)
		S+=cross(p[i]-p[0],p[i+1]-p[0]);
	return S/2;
}

  

凸包:

//凸包
const int N = 400000+10;
const double PI = acos(-1.0);
const double eps = 1e-12;

int dcmp(double x) {
	if(fabs(x)<eps) return 0; else return x<0? -1:1;
}

struct Pt {
	double x,y;
	Pt(double x=0,double y=0) :x(x),y(y) {};
};
typedef Pt vec;

vec operator - (Pt a,Pt b) { return vec(a.x-b.x,a.y-b.y); }
vec operator + (vec a,vec b) { return vec(a.x+b.x,a.y+b.y); }
bool operator == (Pt a,Pt b) {
	return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;
}
bool operator < (const Pt& a,const Pt& b) {
	return a.x<b.x || (a.x==b.x && a.y<b.y);
}

vec rotate(vec a,double x) {
	return vec(a.x*cos(x)-a.y*sin(x),a.x*sin(x)+a.y*cos(x));
}
double cross(vec a,vec b) { return a.x*b.y-a.y*b.x; }
double dist(Pt a,Pt b) {
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

vector<Pt> ConvexHull(vector<Pt> p) {
	sort(p.begin(),p.end());
	p.erase(unique(p.begin(),p.end()),p.end());
	int n=p.size() , m=0;
	vector<Pt> ch(n+1);
	for(int i=0;i<n;i++) {
		while(m>1 && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
		ch[m++]=p[i];
	}
	int k=m;
	for(int i=n-2;i>=0;i--) {
		while(m>k && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
		ch[m++]=p[i];
	}
	if(n>1) m--;
	ch.resize(m); return ch;
}

  

半平面交:

//半平面交

const int N =  305;
const double bond = 100001;
const double eps = 1e-10;

struct Pt {
	double x,y;
	Pt (double x=0,double y=0):x(x),y(y){}
};
typedef Pt vec;

vec operator + (Pt a,Pt b) { return vec(a.x+b.x,a.y+b.y); }
vec operator - (Pt a,Pt b) { return vec(a.x-b.x,a.y-b.y); }
vec operator * (Pt a,double p) { return vec(a.x*p,a.y*p); }

double cross(Pt a,Pt b) { return a.x*b.y-a.y*b.x; }

struct Line {
	Pt p; vec v; double ang;
	Line () {}
	Line (Pt p,vec v) :p(p),v(v){ ang=atan2(v.y,v.x); }
	bool operator < (const Line& rhs) const {
		return ang<rhs.ang;
	}
};

bool onleft(Line L,Pt p) { return cross(L.v,p-L.p)>0; }
Pt LineInter(Line a,Line b)
{
	vec u=a.p-b.p;
	double t=cross(b.v,u)/cross(a.v,b.v);
	return a.p+a.v*t;
}
vector<Pt> HPI(vector<Line> L)
{
	int n=L.size();
	sort(L.begin(),L.end());
	int f,r;
	vector<Pt> p(n) , ans;
	vector<Line> q(n);
	q[f=r=0]=L[0];
	for(int i=1;i<n;i++) {
		while(f<r&&!onleft(L[i],p[r-1])) r--;
		while(f<r&&!onleft(L[i],p[f])) f++;
		q[++r]=L[i];
		if(fabs(cross(q[r].v,q[r-1].v))<eps) {
			r--;
			if(onleft(q[r],L[i].p)) q[r]=L[i];
		}
		if(f<r) p[r-1]=LineInter(q[r-1],q[r]);
	}
	while(f<r&&!onleft(q[f],p[r-1])) r--;
	if(r-f<=1) return ans;
	p[r]=LineInter(q[r],q[f]);
	for(int i=f;i<=r;i++) ans.push_back(p[i]);
	return ans;
}

  

时间: 2024-11-07 07:49:38

[信息学]省选前模板整理的相关文章

省选前模板复习

PREFACE 也许是OI生涯最后一场正式比赛了,说是省选前模板,其实都是非常基础的东西,穿插了英文介绍和部分代码实现 祝各位参加JXOI2019的都加油吧 也希望今年JX能翻身,在国赛中夺金 数学知识 见数学知识小结 字符串 KMP算法Knuth-Morris-Pratt Algorithm KMP算法,又称模式匹配算法,是用来在一个文本串(text string)s中找到所有模式串(pattern)w出现的位置. 它是通过当失配(mismatch)发生时,模式串本身能提供足够的信息来决定下一

ijwmh1-2-以前学习整理出来的学习内容--什么是变量1整型变量

崧闱旭 ijwmh1-2-以前学习整理出来的学习内容--什么是变量1整型变量

HDU 1031 Design T-Shirt 选前k大

相当于给出一组数列,然后选择前K大的数的算法. 本题没有给出详细的数据,故此就使用动态分配空间的方法了. 而这种题最好的算法就是使用快排思想,期望时间效率就是O(n)了. 最基本入门解决这种题的算法是直接排序了.那就成了水代码了.用上快排的思想才能体现出水平. 不过这种快排实在考的太多了,建议一定要掌握. 每次做这个算法的题目总会要调试一定时间的,每次都出现奇葩的错误.看来还是不够细心. 做题的时候一定要排除杂念,有干扰,后果很严重,会花长很多时间. 靖空间做题,一定要静,达到一种禅的境界.说禅

『嗨威说』常见的C++函数模板整理(一)

开学两天,身上的职责直接变为两个班班长,三个小组组长,哇这事情估计够我忙活了,想躲都躲不掉啊,看来我还是真招人推荐各种管理职务啊,以后要是有人推荐我当经理啊领导啊该多好哈哈哈哈.记得今天奶奶生日,很开心地给奶奶打了一通电话,这怕是我第一次给奶奶电话送生日祝福了哈哈哈,是啊,很想珍惜身边的人,但很多时候却一心想提高自己地能力而忽视了身边人,就这四年,就这四年好好提升自己,毕业出来一定要好好陪陪家里祖辈亲戚们. 今天有点特殊,我整理了一下学到这么久编程以来的一些模板和技巧,虽然还没整理完,就作为(一

手机客户端接口开发文档模板整理

这是个人整理的手机开发文档模板,方便自己以后编写文档. 大体内容如下,详细在个人csdn中下载: 移动端转发短信上传温湿度信息 移动端负责后台接收温湿度传感器通过短信发来的温湿度和经纬度信息,移动端后台接收后上传web服务器,当然传感器也可通过wifi直接上传web服务器.返回小写true或者false. 请求URL: http://192.168.1.101:8080/RFID/addTransTemperature.action?phoneNumber=123&temperature=12.

写在省选前

以往我都会对每一场比赛进行很长时间的yy,把各种可能的结果都想了.后来结果出来既不会太糟又不会太好. 但是我很久没有享受过一场比赛了. gdkoi的时候我被虐的很惨,然后我很生气,然后我想在最后的时候争取一下.我还记得那天晚上,我一页一页翻看云的空间,整理了109道题,对自己说:写完它. 我写下那篇退役?再搏一次! 结果是没有写完,我觉得原因是我在最后的时候还是有点偷懒的. 但是我争取了.我觉得我没写完这个结果我可以接受,或者如果我写完它我可能会很高兴吧.但是更重要的时,从里面的题,我回顾了我这

省选前的做题记录(Round2)

[CF1109B] Sasha and One More Name 先把无解情况aaabaaa.aaaaaa判掉,然后我们可以证明答案不会超过2. 对于一个回文串,两个指针从两端向内移动直到字符发生变化,在这里看一刀然后交换左右两端即为一种合法方案. 所以我们只需要判断答案是否能为\(1\),暴力判即可. [CF1109C] Sasha and a Patient Friend 假设我们有一个序列数据结构,那么先考虑每个结点需要维护哪些值才能支持合并左右儿子. 维护: 当前点时刻\(time\)

ACM模板整理|2019/12/27

看到群里都是18.19级的学弟,才发现自己老了啊?? 还算充实的一天,就是电影还没看.. 最短路 Floyd 应用 1.Floyd求有向图最小环:枚举g[i][i] 2.Floyd求无向图最小环: if (f[k][i] && f[k][j] ) { ans = min(e[i][j]+2,ans); } const int inf = 0x3f3f3f3f; int g[MAX_N][MAX_N]; // 算法中的 G 矩阵 // 首先要初始化 g 矩阵 void init() { fo

【POJ 3241】曼哈顿最小生成树(模板整理)

关于 曼哈顿最小生成树 的证明见:http://www.2cto.com/kf/201505/399861.html 模板: #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 100010; const int INF = 0x3f3f3f3f; struct Point{ int x,y,i