Nov 19

话说我写记录的模拟赛怎么都是没有打好的

T1 : S2 1697

发现了 \(x\)\(a[i]\) 很小,我们从这里入手,似乎每一次询问最多只会搞 9 个人,我们直接对于每一个位置预处理出来每一个值在当前位置(包含)下一次出现的位置。

之后对于每一次询问,我们可以直接枚举子集,然后看最近可以跳到哪里。

来分析一下时间问题,枚举子集是 \(2^{popcount(x)}\) 的,然后每一次是最多 9 次的,再加上每一次是不可能跑慢的,所以我们是可以卡过去的,就没有然后了,不过最差我并不知道可不可以卡过去,如过硬要去求一个最差,就是 \(O(q\times \sum_{i=1}^{9} 2^i)\),因为我们的小常数也问题不大,我们把各种优化全部加上去就行了。

点击查看代码
#include <bits/stdc++.h>
#define int long long
#define getchar getchar_unlocked
using namespace std;
const int MN=56666;
int n, q, a[MN], b[MN], nxt[MN][1024], maxn=0, ans=0;
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*10+ch-'0',ch=getchar();
    return x*f;
}
void Read(){
	n=read();
	for(int i=1; i<=n; ++i) a[i]=read();
	for(int i=1; i<=n; ++i) b[i]=read();
	q=read();
}
int query(int l, int r, int x){
	int res=0, pos=l;
	while(x){
		int v=0x3f3f3f3f;
		for(int i=x; i; i=(i-1)&x){
			v=min(v,nxt[pos][i]);
		}
		if(v>r) break;
		pos=v+1; res+=b[v];
		x^=a[v];
	}
	return res;
}
void Solve(){
	Read(); memset(nxt,0x3f,sizeof(nxt));
	for(int i=1; i<=n; ++i){
		maxn=max(maxn,a[i]);
		nxt[i][a[i]]=i;
	}
	for(int i=n-1; i>=1; --i){
		for(int j=1; j<=maxn; ++j){
			nxt[i][j]=min(nxt[i][j],nxt[i+1][j]);
		}
	}
	while(q--){
		int l, r, x;
		l=read(); r=read(); x=read();
		ans^=query(l,r,x);
	}
	cout<<ans<<'\n';
	return;
}
signed main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	Solve();
	return 0;
}

T2:S2 1698

一道脑电波题目,反正我并没能想出来就是了。

我们将这个问题先放到一道链上考虑会轻松一些,我们去思考这个链长度是 1 2 3 4 5的情况下的答案是多少。

发现答案是 1 2 1 2 1 2 1 2 1 2 1 ........

之后就简简单单了,我们发现答案仅仅同两点的长度的奇偶性有关系。

我们就维护每一个联通快,每一个联通快 dfs 一波,按照奇偶性搞一下。

如果两个点奇偶性不同,就是 1,否则是 2.

需要特殊判断一下 0 和 -1.

代码↓

点击查看代码
#include <bits/stdc++.h>
#define int long long
#define getchar getchar_unlocked
/*
| %%%%%%% --- %%%%%%%  |
| method by langmouren |
| %%%%%%% --- %%%%%%%  |
*/
using namespace std;
const int MN=3e6+316;
struct Node{
	int nxt, to;
}node[MN];
int n, m, q, odd[MN], even[MN], belong[MN], cnttt;
int head[MN], tottt=0;
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*10+ch-'0',ch=getchar();
    return x*f;
}
void insert(int u, int v){
	node[++tottt].to=v;
	node[tottt].nxt=head[u];
	head[u]=tottt; return;
}
void dfs(int u, int father, int id){
	belong[u]=id;
	for(int i=head[u];i;i=node[i].nxt){
		int v=node[i].to;
		if(v==father) continue;
		if(odd[u]&&!even[v]){
			even[v]=true;
			dfs(v,u,id);
		}
		if(even[u]&&!odd[v]){
			odd[v]=true;
			dfs(v,u,id);
		}
	}
}
void Read(){
	n=read(); m=read();
	for(int i=1; i<=m; ++i){
		int u, v; u=read(); v=read();
		insert(u,v); insert(v,u);
	}
	for(int i=0; i<=n; ++i){
		if(!belong[i]){
			even[i]=true;
			dfs(i,i,++cnttt);
		}
	}
	q=read();
	return;
}
void Solve(){
	Read();
	while(q--){
		int s, t; s=read(); t=read();
		if(s==t) cout<<0<<'\n';
		else if(belong[s]!=belong[t]) cout<<-1<<'\n';
		else if((odd[s]&&even[t])||(even[s]&&odd[t])) cout<<1<<'\n';
		else cout<<2<<'\n';
	}
	return;
}
signed main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int BaiBaiShaFeng; BaiBaiShaFeng=read(); Solve();
	return 0;
}
posted @ 2025-11-19 15:29  BaiBaiShaFeng  阅读(2)  评论(0)    收藏  举报
Sakana Widget右下角定位