20240917【省选】模拟

难说

T1

暴力可以写dp

只要你学过线性基那么你就会想怎么用线性基做,显然是要套点数据结构维护的。你要知道两个线性基可以在 O(log2n) 的时间内合并,得到的线性基是原来两个的交。可以用线段树维护,复杂度 O((n+q)lognlog2a),难说能不能过。

没有修改,所以考虑用常熟小一点的数据结构,可以用ST表维护最值,复杂度 O(nlognlog2a+qlog2a),小了一点。

发现瓶颈在于 log2a 的合并,看能不能优化成一个老哥。一个简单的思路是分治,把询问离线下来,处理跨过中点的询问,就只会对线性基产生 O(nlogn) 次的修改,复杂度被优化成 O(nlognloga+qlog2a),好像能过了。

然后是正解,看不懂:

啥都能扫描线(

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll int
#define in inline
const ll N=1145140,M=1919810,inf=2e9,V=29;
ll n,Q,a[N],f[N],p[N],x;
ll ans[N];
struct xx{
	ll l,r,d,id;
}q[N];
bool cmp(xx x,xx y){
	return x.r<y.r;
}
bool flag;
void insert(ll x,ll id){
	for(ll i=V;i>=0;--i)
		if(x&(1ll<<i)){
			if(!f[i]){
				f[i]=x,p[i]=id;
				return;
			}
			else{
				if(id>p[i]){
					swap(id,p[i]);
					swap(x,f[i]);
				}
				x^=f[i];
			}
		}
	flag=1;
}
ll qmax(ll d,ll l){
	for(int i=V;i>=0;--i)
		if(p[i]>=l) d=max(d,d^f[i]);
	return d;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	n=read();
	for(int i=1;i<=n;++i) a[i]=read();
	Q=read();
	for(int i=1;i<=Q;++i) q[i].l=read(),q[i].r=read(),q[i].d=read(),q[i].id=i;
	//cin>>q[i].l>>q[i].r>>q[i].d,q[i].id=i;
	sort(q+1,q+Q+1,cmp);
	for(int i=1,j=1;i<=Q;++i){
		while(j<=q[i].r){
			insert(a[j],j);
			++j;
		}
		ans[q[i].id]=qmax(q[i].d,q[i].l);
	}
	for(int i=1;i<=Q;++i) write(ans[i]),putchar('\n');
	return 0;
}

T2

应该冲正解的,这个题其实真的挺简单的,就是建图。你会发现一个点能早到就尽量早到,不会因为可能错开车而使得时间不优。注意不需要在不同线路之间建边。

对每条线路把这个环建出来,每天边要记录 u 在线路中的下标(从 0 开始)和线路的长度用于计算到达时间。用 dij和SPFA 都行,但松弛过程中边权是根据 u 在线路中的位置和 dis[u] 确定的,具体看代码,很容易手推出来。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define eb emplace_back
#define pi pair<ll,ll>
const ll N=2*114514,M=1919810,inf=1e18;
ll n,m,t[N];
struct xx{
	ll v,t,le;
};
ll dis[N];
bool vis[N];
vector <xx> g[N];
priority_queue <pi,vector<pi>,greater<pi>> q;
void dij(){
	memset(dis,63,sizeof(dis));
	dis[1]=0,q.push({dis[1],1});
	while(!q.empty()){
		ll u=q.top().second; q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(xx x:g[u]){
			ll v=x.v,t=x.t,le=x.le,w=0;
			if(dis[u]%le<=t) w=t-dis[u]%le+1;
			else w=le-dis[u]%le+t+1;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				q.push({dis[v],v});
			}
		}
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=m;++i){
		cin>>t[i];
		vector <ll> a;
		for(int j=1,x;j<=t[i];++j) cin>>x,a.eb(x);
		for(int j=0;j<t[i];++j) g[a[j]].eb((xx){a[(j+1)%t[i]],j,t[i]});
	}
	dij();
	for(int i=2;i<=n;++i)
		if(dis[i]==dis[0]) cout<<"-1 ";
		else cout<<dis[i]<<" ";
	return 0;
}

T3

智慧题。但是本来是把结论都推出来了,39pts的代码也打出来了,但是连犯两个最低级的错误,然后就没了。

不会。

posted @   和蜀玩  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示