2018.11.7【模板题】模拟赛

模板题又没有 A K AK AK手残祭

首先是 S T ST ST表,这个虽然不怎么常写但还是 A A A

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 200005
#define int long long
using namespace std;

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f;
}
inline int max(int x,int y){return x>y?x:y;}

int n,m,a[maxn],f[maxn][25];

inline void prework(){
	int t=log2(n)+1;
	for(int i=1;i<=n;i++) f[i][0]=a[i];
	for(int j=1;j<=t;j++)
		for(int i=1;i<=n-(1<<j)+1;i++)
			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}

inline int query(int l,int r){
	int k=log2(r-l+1);
	return max(f[l][k],f[r-(1<<k)+1][k]);
}

signed main(){
//	freopen("in.txt","r",stdin);
//	freopen("out2.txt","w",stdout);
	freopen("st.in","r",stdin);
	freopen("st.out","w",stdout);
	n=rd(); memset(f,0xcf,sizeof f);
	for(int i=1;i<=n;i++) a[i]=rd();
	m=rd(); prework();
	while(m--){
		int x=rd(),y=rd();
		if(x>y) swap(x,y);
		printf("%lld\n",query(x,y));
	}
	return 0;
}
/*
6
34 1 8 123 3 2
4
1 2
1 5
3 4
2 3
*/

线性筛素数, A C AC AC

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 10000001
#define LL long long
using namespace std;
int n,cnt,pri[maxn];
LL sum;
bool vis[maxn];

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f;
}

inline void get_prime(){
	for(int i=2;i<=n;i++){
		if(!vis[i]) pri[++cnt]=i;
		for(int j=1;j<=cnt && i*pri[j]<=n;j++){
			vis[i*pri[j]]=1;
			if(i%pri[j]==0) break;
		}
	}
} 

int main(){
	freopen("prime.in","r",stdin);
	freopen("prime.out","w",stdout);
	n=rd();
	get_prime();
	for(int i=1;i<=cnt;i++) sum+=pri[i];
	printf("%lld\n",sum);
	return 0;
}

s p f a spfa spfa判负环,这个以前没写过或者是很久远的事了总之考试的时候虚的一批但还是 A A A

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define N 505
#define M 3005
using namespace std;

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f;
}

int t,n,m,W,cnt,head[N],inst[N],dis[N];
bool vis[N];
queue<int> q;

struct EDGE{
	int to,nxt,w;
}edge[M<<1];
inline void add(int x,int y,int z){
	edge[++cnt].to=y; edge[cnt].nxt=head[x]; edge[cnt].w=z;
	head[x]=cnt;
}

inline bool spfa(){
	memset(vis,0,sizeof vis); memset(dis,0x3f,sizeof dis);
	while(!q.empty()) q.pop(); memset(inst,0,sizeof inst);
	q.push(1); dis[1]=0; inst[1]++;
	while(!q.empty()){
		int u=q.front(); q.pop();
		vis[u]=0;
		if(inst[u]>n) return true;
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			if(dis[v]>dis[u]+edge[i].w){
				dis[v]=dis[u]+edge[i].w;
				if(!vis[v]){
					q.push(v); vis[v]=1;
					inst[v]++;
				}
			}
		}
	} return false;
}

int main(){
	freopen("spfa.in","r",stdin);
	freopen("spfa.out","w",stdout);
	t=rd();
	while(t--){
		n=rd(); m=rd(); W=rd();
		int x,y,z; cnt=0; memset(head,0,sizeof head);
		for(int i=1;i<=m;i++){
			x=rd(),y=rd(),z=rd();
			add(x,y,z); add(y,x,z);
		}
		for(int i=1;i<=W;i++){
			x=rd(),y=rd(),z=rd();
			add(x,y,-z);
		}
		if(spfa()) puts("YES");
		else puts("NO");
	}
	return 0;
}
/*
2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8
*/

t a r j a n tarjan tarjan有向图缩点,昨天写一个点双的题,点双不需要 v i s vis vis,然后今天写的时候忘记写 v i s [ u ] = 1 vis[u]=1 vis[u]=1,手残啊手残(虽然就这样还有 50 50 50分??)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define N 10005
#define M 50005
using namespace std;

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f;
}

int n,m,cnt,head[N],dfn[N],low[N],stk[N],num,top,tot;
int bel[N],d[N];
bool vis[N];
vector<int> vec[N];

struct EDGE{
	int to,nxt;
}edge[M];
inline void add(int x,int y){
	edge[++cnt].nxt=head[x]; edge[cnt].to=y; head[x]=cnt;
}

inline void tarjan(int u){
	dfn[u]=low[u]=++num; stk[++top]=u; vis[u]=1;//vis!!
	for(int i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(vis[v]) low[u]=min(low[u],dfn[v]);
	}
	if(dfn[u]==low[u]){
		++tot; int tmp;
		do{
			tmp=stk[top--]; vis[tmp]=0;
			vec[tot].push_back(tmp); bel[tmp]=tot;
		}while(tmp!=u);
	} return;
}

inline void rebuild(){
	for(int u=1;u<=n;u++)
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			if(bel[v]!=bel[u]) d[bel[u]]++;
		}
}

int main(){
	freopen("tarjan.in","r",stdin);
	freopen("tarjan.out","w",stdout);
	n=rd(); m=rd();
	for(int i=1;i<=m;i++){
		int x=rd(),y=rd();
		add(x,y);
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i]) tarjan(i);
	rebuild(); cnt=0;
	for(int i=1;i<=tot;i++)
		if(!d[i]) cnt++;
	if(cnt>1) {puts("0");return 0;}
	cnt=0;
	for(int i=1;i<=tot;i++)
		if(!d[i]) cnt+=vec[i].size();
	printf("%d\n",cnt);
	return 0;
}
/*
3 3
1 2
2 1
2 3
*/

L C A LCA LCA,听说都是树剖写的,但我懒我喜欢倍增 q w q qwq qwq

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 100005
using namespace std;

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f; 
}

int n,q,cnt,head[N],f[N][20],dep[N];

struct EDGE{
	int to,nxt;
}edge[N<<1];
inline void add(int x,int y){
	edge[++cnt].to=y; edge[cnt].nxt=head[x]; head[x]=cnt;
}

void dfs(int u,int fa){
	for(int i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(v==fa) continue;
		dep[v]=dep[u]+1; f[v][0]=u;
		for(int j=1;j<=18;j++)
			f[v][j]=f[f[v][j-1]][j-1];
		dfs(v,u);
	} return;
}

inline int LCA(int x,int y){
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=18;i>=0;i--)
		if(dep[f[x][i]]>=dep[y]) x=f[x][i];
	if(x==y) return x;
	for(int i=18;i>=0;i--)
		if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
	return f[x][0];
}

int main(){
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout); 
	n=rd();
	for(int i=1;i<n;i++){
		int x=rd(),y=rd();
		add(x,y); add(y,x);
	}
	dep[1]=1; dfs(1,0);
	q=rd();
	while(q--){
		int x=rd(),y=rd(),z=LCA(x,y);
		printf("%d\n",dep[x]+dep[y]-2*dep[z]);
	}
	return 0;
}
/*
6
1 2
1 3
2 4
2 5
3 6
2
2 6
5 6
*/ 

这两次模板题都没全对 Q A Q QAQ QAQ,大后天就要考试了····算了就当攒 r p rp rp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值