2022.7.12 模拟赛

2022.7.12 模拟赛#

牛半仙的妹子数#

题意

给你 T 组数据,每组数据给你 4 个数 a,b,c,k,你需要进行 k 次操作

假定 x=a+b,则每次:

  • xc,则 c=cx,x=2x
  • 否则 x=xc,c=2c

求出 k 次操作后 c 的值

1T105,1a,b,c,k109

思路

容易发现在这两种操作下 c+x 值恒定

第一种操作 c=cx=c(c+x)+c=2c(c+x)=2cmodx

第二种操作 c=2c=2cmodx

最后 c=c2kmod(c+x)

快速幂求解

code

#include<bits/stdc++.h>
using namespace std;

#define int long long

inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}

int mod;

inline int qpow(int x,int idx){
	if(!idx) return 1;
	int t=qpow(x,idx>>1);
	if(idx&1) return t*t%mod*x%mod;
	return t*t%mod;
}

inline void solve(){
	int a=read(),b=read(),c=read(),k=read();
	mod=a+b+c;
	cout<<qpow(2,k)*c%mod<<endl;
}

signed main(){
	int T=read();
	while(T--){
		solve();
	}
}

人类智慧题,考场上想了一个小时最后写了暴力

(所以我没有智慧)

牛半仙的妹子图#

题意

给你一个 n 个点 m 条边的无向图以及图中的起始点 rt ,每条边 i 有一个权值 wi,每个点有一个颜色 ci

每次你会从 rt 出发,走向所有能走到的点,若这次最大承受值x,则你经过的所有边的边权必须小于等于 x

你每次出发获得的价值是你到的所有点总共的不同颜色数

给你 q 次询问,每次给你两个数 l,r

你需要求出 i=lrrt 出发最大承受值为 i 的价值

本题强制在线

1n,m5×105,1q105,1wi,l,r109,1ci600

思路

容易有一个想法就是求出到达每一个点的最短路,从而求出遍历到每个颜色的最大承受值最小是多少

这个可以跑一个 spfa

由于强制在线,so 不能用莫队 QAQ

由于 ci600 ,可以考虑枚举每一个颜色最小的最大承受值,然后统计每个颜色对 [l,r] 有多少贡献

这样的期望时间复杂度是 O(km+600q),其中 kspfa 的常数

code

#include<bits/stdc++.h>
using namespace std;

const int N=5e5+5;
const int C=505;
const int inf=1e9+5;

#define pb push_back
#define int long long
#define re register 

inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}

struct node{
	int a,b;
};

struct pt{
	int c,x;
	inline bool operator < (const pt X) const{
		return x<X.x;
	}
}a[N];


vector <node> G[N];
vector <int> p;

int n,m,rt,op,mod,cnt;
int c[N],d[605];
int dis[N],vis[N];

inline void spfa(){
	for(int i=1;i<=n;++i) dis[i]=inf;
	vis[rt]=1;
	dis[rt]=0;
	queue <int> q;
	q.push(rt);
	while(!q.empty()){
		re int x=q.front();
		q.pop();
		vis[x]=0;
		for(auto y:G[x]){
			if(dis[y.a]>max(dis[x],y.b)){
				dis[y.a]=max(dis[x],y.b);
				if(!vis[y.a]) q.push(y.a),vis[y.a]=1;
			}
		}
	}
	for(int i=1;i<=n;++i){
		a[i].c=c[i],a[i].x=dis[i];
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;++i){
		if(a[i].x!=inf){
			if(!d[a[i].c])
				d[a[i].c]=1,p.push_back(a[i].x);
		}
	}
	sort(p.begin(),p.end());
}

int q;

signed main(){
	n=read(),m=read(),q=read(),rt=read(),op=read();
	if(op==1) mod=read();
	for(int i=1;i<=n;++i) c[i]=read();
	for(int i=1;i<=m;++i){
		int x=read(),y=read(),z=read();
		G[x].pb({y,z});
		G[y].pb({x,z});
	}
	spfa();
	int last=0;
	while(q--){
		//cout<<"qwq"<<endl;
		re int l=read(),r=read();
		if(op) l=(l^last)%mod+1;
		if(op) r=(r^last)%mod+1;
		if(l>r) swap(l,r);
		re int ans=0ll;
		for(re int i=0;i<(int)p.size();++i){
			//cout<<p[i]<<endl;
			if(p[i]>r) break;
			ans+=(r-max(p[i],l)+1);
			//cout<<ans<<endl;
		}
		last=ans;
		printf("%lld\n",ans);
	}
}

考试的时候 spfa 写出来了,但转移的时候还是下意识的写了 dis[y.a]=dis[x]+y.b,实际上应该是 dis[y.a]=max(dis[x],y.b)

关键是考场上没写对拍,而且在我的玄学改法下过了样例

然后 100pts0pts,我好恨啊 qaq

牛半仙的妹子 Tree#

题意

给你一个 n 个点 n1 条边的树以及一个数 m

每个点 i 有一个点权 wi,初始均为 0

接下来有 m 次操作,每次给你两个数 opx

每个操作一秒钟

  • op=1 则将 wx 改为 1,并扩散
  • op=2 则将所有点点权改为 0
  • op=3 则询问这一秒结束 wx 是否为 1

注意,扩散是指:当一个点点权在第 i 秒被改为 1 后会在第 i+1 秒将所有与其相邻的点点权改为 1

1n,m105,1xn,1op3

思路

考虑若是没有操作 2 这题可以直接一个 bfs 解决

因此考虑根据每一个 2 操作将此问题分成多段

分情况考虑此问题,类似于一个分块的思想

若是第 i2 操作到第 i+12 操作之间的操作数 k 小于等于 3000,则跑 O(k2logk) 的暴力

否则可以跑 bfs,时间复杂度是 O(nmk)

这样算下来总的复杂度是 O(k2logk+nmk) 的,可以跑过此题

这题的 k 可以依据写的暴力的速度而定,我这个暴力就跑得很快

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+5;
const int inf=1e9+5;

inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}

int n,m;
int f[N][20],dep[N];
int d[N];

struct node{
	int x,t;
	inline bool operator < (const node X) const{
		return t<X.t;
	}
};

vector <node> p;
set <node> s;
vector <int> G[N];

inline void bfs(){
	for(int i=1;i<=n;++i) d[i]=inf;
	queue <int> q;
	for(auto x:s){
		if(d[x.x]==inf) d[x.x]=x.t;
		q.push(x.x);
	}
	while(!q.empty()){
		int x=q.front();q.pop();
		for(auto y:G[x]){
			if(d[y]>d[x]+1){
				q.push(y);
				d[y]=d[x]+1;
			}
		}
	}
	for(auto y:p){
		if(y.t>=d[y.x]){puts("wrxcsd");}
		else{puts("orzFsYo");}
	}
}

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

inline void dfs(int x,int fa){
	f[x][0]=fa;
	dep[x]=dep[fa]+1;
	for(int i=1;i<=17;++i)
		f[x][i]=f[f[x][i-1]][i-1];
	for(auto y:G[x]){
		if(y==fa) continue;
		dfs(y,x);
	}
}

inline void brute_force(){
	for(auto x:p){
		bool flag=0;
		for(auto y:s){
			int a=x.x,b=y.x;
			if(dep[a]+dep[b]-2*dep[lca(a,b)]<=x.t-y.t){
				flag=1;
				puts("wrxcsd");
				break;
			}
		}
		if(!flag) puts("orzFsYo");
	}
}

signed main(){
	n=read(),m=read();
	for(int i=1;i<n;++i){
		int x=read(),y=read();
		G[x].push_back(y);
		G[y].push_back(x);
	}
	int pre=0;
	dfs(1,0);
	for(int T=1;T<=m;++T){
		int op=read(),x=read();
		if(op==1){
			s.insert({x,T});
		}
		if(op==2){
			if(T-pre<=3000) brute_force();
			else bfs();
			pre=T;
			s.clear(),p.clear();
		}
		if(op==3){
			p.push_back({x,T});
		}
		if(T==m&&op!=2){
			if(T-pre<=3000) brute_force();
			else bfs();
		}
	}
}

woc解法好暴力

不过考场上没有想到 qwq

牛半仙的魔塔(增强版)#

这题在图上跑贪心?没有理解

所以不写了

作者:Into_qwq

出处:https://www.cnblogs.com/into-qwq/p/16471545.html

版权:本作品采用「qwq」许可协议进行许可。

posted @   Into_qwq  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示