CSP2025模拟赛5

ooliver OI

S+CSP2025模拟赛5

A. 逆转

按时间模拟即可, 懒得一个一个加分数,所以把连续的得分合并了一下, 代码:

#include
using namespace std;
const int N=3005;
struct node{
	int t,id;
}f[N];
int a,b,x,idx;
int s1,s2,ans1,ans2;
vector v;
bool cmp(node x,node y){return x.t>a;
	while(a--){
		cin>>x,v.push_back({x,1});
		if(x>b;
	while(b--){
		cin>>x,v.push_back({x,2});
		if(xs2) ans2++;
			s1+=f[i].t;
		}
		if(f[i].id==2){
			if(s1>s2&&s1
`#include
using namespace std;
const int N=3005;
struct node{
	int t,id;
}f[N];
int a,b,x,idx;
int s1,s2,ans1,ans2;
vector v;
bool cmp(node x,node y){return x.ty.t;}
int main(){
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
	cin>>a;
	while(a--){
		cin>>x,v.push_back({x,1});
		if(x1440) ans1++;
	} 
	cin>>b;
	while(b--){
		cin>>x,v.push_back({x,2});
		if(x1440) ans1++;
	}
	sort(v.begin(),v.end(),cmp);
	for(int i=0;iv.size();i++){
		int cnt=1;
		while(v[i+1].id==v[i].id) i++,cnt++;
		f[++idx]={cnt,v[i].id};
	}
	for(int i=1;i
		if(f[i].id==1){
			if(s1f[i].t>s2) ans2++;
			s1+=f[i].t;
		}
		if(f[i].id==2){
			if(s1>s2&&s1f[i].t) ans2++;
			s2+=f[i].t;
		}
	}
	cout
	return 0;
}`

C++

B. 约数计数

观察到 m 比较小,考虑对数组进行操作。
可以先用map存下每个因数出现了多少次,
再按次数统计因数的个数即可,
最后直接输出答案。 (0 的情况就是 n 减去所有范围内的因数的种类数) 代码:

#include
using namespace std;
const int N=205;
int n,m,cnt;
int a[N],ans[N];
unordered_map m1;
void f(int x){
	for(int i=1;i*i>n>>m;
	for(int i=1;i>a[i];
		f(a[i]);
	}
	for(auto u:m1){
		int x=u.first,y=u.second;
        if(x>=1&&x
`#include
using namespace std;
const int N=205;
int n,m,cnt;
int a[N],ans[N];
unordered_mapint,int> m1;
void f(int x){
	for(int i=1;i*iif(x%i==0&&i
		if(i!=x/i) m1[i]++,m1[x/i]++;
		else m1[i]++;
	}
}
int main(){
	freopen("div.in","r",stdin);
	freopen("div.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i
		cin>>a[i];
		f(a[i]);
	}
	for(auto u:m1){
		int x=u.first,y=u.second;
        if(x>=1&&x
            ans[y]++;
            cnt++;
        }
	}
    cout
    for(int i=1;ians[i]
	return 0;
}`

C++

C. 集合查找

对于操作一,我们统计每个因数的倍数,方便在操作二中找gcd。 而对于操作二,我们贪心的从二进制最高位到最低位二分查找亦或后某一位是 1 的方案是否可行, 统计答案输出即可。 代码:

#include 
using namespace std;
#define int long long
const int N=1e5+5;
set v[N];
int q;
main() {
    freopen("set.in","r",stdin);
    freopen("set.out","w",stdout);
    cin>>q;
    while(q--) {
        int t;
        cin>>t;
        if(t==1) {
            int u;
            cin>>u;
            for(int i=1;i*i>x>>k>>s;
            s-=x;
            if(x%k||s=0;i--){
                if(!y) break;
                auto it=v[k].lower_bound(ans+(1=ans);
                if(!f1&&!f2){
                    cout>i)&1)) ans+=(1
`#include 
using namespace std;
#define int long long
const int N=1e5+5;
setint> v[N];
int q;
main() {
    freopen("set.in","r",stdin);
    freopen("set.out","w",stdout);
    cin>>q;
    while(q--) {
        int t;
        cin>>t;
        if(t==1) {
            int u;
            cin>>u;
            for(int i=1;i*i
                if (u%i==0) {
                    v[i].insert(u);
                    if(i!=u/i) v[u/i].insert(u);
                }
            }
        }
        else{
            int x,k,s;
            cin>>x>>k>>s;
            s-=x;
            if(x%k||s0){
                cout"-1\n";
                continue;
            }
            bool y=1;
            int ans=0;
            for(int i=(!s?0:log2(s));i>=0;i--){
                if(!y) break;
                auto it=v[k].lower_bound(ans+(1
                bool f1=(it!=v[k].end()&&*itmin(s,ans+(11))-1));
                bool f2=(it!=v[k].begin()&&*prev(it)>=ans);
                if(!f1&&!f2){
                    cout"-1\n";
                    y=0;
                } 
                else if(f1&&!f2) ans+=(1
                else if(f1&&f2&&!((x>>i)&1)) ans+=(1
            }
            if(y) cout"\n";
        }
    }
    return 0;
}`

C++