CSP-S 赛前模板复习

快读模板

这个连算法都算不上。。。

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<<3)+(x<<1)+(ch^48); ch=getchar(); }
	return x * f;
}

二分查找

这是我学过的第一个算法qwq

sort(a+1, a+1+n);
bool Find(int x) {	//二分查找x在a中是否出现 
	int l = 1, r = n, mid;
	while(l <= r) {
		mid = (l+r)>>1;
		if(x == a[mid]) return 1;
		if(x < a[mid]) r = mid - 1;
		else l = mid + 1;
	}
	return 0;
}

二分答案

bool check() {
	
}
int main()
{	
	// 单调递增答案 使最大值最小 
	int l = (), r = (), mid, ans;
	while(l <= r) {
		mid = (l+r)>>1;
		if(check()) {
			ans = mid;
			r = mid - 1;
		} else l = mid + 1;
	}
	printf("%d\n",ans);
	// 单调递减答案 使最小值最大 
	int l = (), r = (), mid, ans;
	while(l <= r) {
		mid = (l+r)>>1;
		if(check()) {
			ans = mid;
			l = mid + 1;
		} else r = mid - 1;
	}
	return 0;
}

离散化

const int N = 1e6+7;
int n;
int a[N],t[N];
int main()
{
	n = read();
	for(int i=1;i<=n;++i)
		t[i] = a[i] = read(); 	//t[] 是临时数组 
	sort(t+1, t+1+n);
	int m = unique(t+1, t+1+n) - (t+1);
	for(int i=1;i<=n;++i)
		a[i] = lower_bound(t+1, t+1+m, a[i]) - t;
	for(int i=1;i<=n;++i)
		printf("%d ",a[i]);	//离散化后数组 
	return 0;
}

ST表 & 倍增一般算法

const int N = 100007;
int n,m;
int lg[N];
int f[N][30];	//f[i,j]表示 [i - 2^j]区间的最大值
void RMQ() {
	for(int j=1;j<=21;++j)
		for(int i=1;i<=n;++i) if(i+(1<<j)-1 <= n) {
			f[i][j] = max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
		}
}
inline int Query(int l,int r) {
	int k = lg[r-l+1];
	return max(f[l][k], f[r-(1<<k)+1][k]);
}
int main()
{
	n = read(), m = read();
	for(int i=1;i<=n;++i)
		f[i][0] = read();
	RMQ();
	for(int i=2;i<=n;++i)
		lg[i] = lg[i>>1] + 1;
	while(m--) {
		int l = read(), r = read();
		printf("%d\n",Query(l,r));
	}
	return 0;
}

KMP

什么?? 我已经不记得KMP的思想了!!??

const int N = 1000007;
int kmp[N];
char a[N],b[N];
int main()
{
	cin>>a+1>>b+1;
	int la = strlen(a+1), lb = strlen(b+1);
	int j = 0;
	for(int i=2;i<=lb;++i) {
		while(j && b[i]!=b[j+1]) j = kmp[j];
		if(b[i] == b[j+1]) ++j;
		kmp[i] = j; 
	}
	j = 0;
	for(int i=1;i<=la;++i) {
		while(j && a[i]!=b[j+1]) j = kmp[j];
		if(a[i] == b[j+1]) ++j;
		if(j == lb) printf("%d\n",i-lb+1), j = kmp[j];
	}
	for(int i=1;i<=lb;++i)
		printf("%d ",kmp[i]);
	return 0;
}

Dfs(有向图)

int vis[N];
void Dfs(int u/*,,,其他状态*/) {
	vis[u] = 1;	/*其他初始化*/
	for(int i=head[u];i;i=edge[i].next /*其他状态转移*/) {
		int v = edge[i].to;
		if(!vis[v] /*&& 其他限制条件*/) {
			//搜索 / 操作 
			Dfs(v);
			//回溯 
		}
	}
}

Bfs(有向图)

int vis[N];
void Bfs(/*传入条件*/) {
	memset(vis, 0, sizeof(vis));
	queue<int> q;
	q.push(1); vis[1] = 1; /*其他初始化*/
	while(!q.empty()) {
		int u = q.front(); q.pop();	//或是其他结构体(状态空间) 
		for(int i=head[u];i;i=edge[i].next) {
			int v = edge[i].to;
			if(!vis[v]) {
				/*其他操作*/ vis[v] = 1; q.push(v);
			}
		}
	}
}

并查集

const int N = 1e5+7;
int n,m;
struct UnionFind {
	int pre[N];
	void Init() {
		for(int i=1;i<=n;++i) pre[i] = i;
	}
	int Find(int x) {
		return x==pre[x]?x:pre[x] = Find(pre[x]);
	}
	void join(int x,int y) {
		int fx = Find(x), fy = Find(y);
		if(fx != fy) pre[fx] = fy;
	}
}B;

树状数组

const int N = 500007;
int n,m;
struct Tree_A {	//树状数组 
	int c[N];
	void Add(int x,int y) {
		while(x<=n) c[x]+=y, x+=x&-x;
	}
	int Sum(int x) {
		int res = 0;
		while(x>0) res += c[x], x-=x&-x;
		return res;
	}
	inline int Query(int x,int y) {
		return Sum(y) - Sum(x-1);
	}
}T;
posted @ 2019-11-12 11:16  基地AI  阅读(216)  评论(0编辑  收藏  举报