CSP-J Day 4 模拟赛补题报告

18 篇文章 1 订阅
4 篇文章 0 订阅

姓名:王胤皓,校区:和谐校区,考试时间: 2024 2024 2024 10 10 10 4 4 4 9 : 00 : 00 9:00:00 9:00:00~ 12 : 30 : 00 12:30:00 12:30:00,学号: S 07738 S07738 S07738

请关注作者的 B 站,谢谢~链接

CSP-J Day 4 4 4 模拟赛补题报告

前言

考了我们班 Rank 1 1 1

分数

T1 three: A c c e p e t e d   100 \color{green}Accepeted\space100 Accepeted 100
T2 fit: A c c e p e t e d   100 \color{green}Accepeted\space100 Accepeted 100
T3 matrix: T L E   20 \color{orange}TLE\space20 TLE 20
T4 pair: T L E   20 \color{orange}TLE\space20 TLE 20

T1

题面

在这里插入图片描述

思路

打标找规律。

赛时 A c c e p e t e d \color{green}{Accepeted} Accepeted 代码

#include<bits/stdc++.h>
using namespace std;
int main(){
	freopen("three.in","r",stdin);
	freopen("three.out","w",stdout);
	int n;
	cin>>n;
	n%=3;
	if(n==0){
		printf("odd\nodd\nodd\n");
	}
	else if(n==1){
		printf("odd\nodd\neven\n");
	}
	else{
		printf("even\neven\nodd\n");
	}
	return 0;
}

T2

题面

在这里插入图片描述

思路

开桶数组,然后利用递推,预处理。

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,tong[1000005],q,x;
int main(){
	freopen("fit.in","r",stdin);
	freopen("fit.out","w",stdout);
	cin.tie(0);
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1; i<=n; i++){
		int x;
		cin>>x;
		tong[x]++;
	}
	for(int i=1; i<=m; i++) tong[i]+=tong[i-1]/2;
	cin>>q;
	while(q--){
		cin>>x;
		cout<<tong[x]<<"\n";
	}
	return 0;
}


T3

题面

在这里插入图片描述

思路

枚举完起始行和终止行之后,还需要去计算结果,这一部分可以考虑优化。
可以按位去考虑,对于某个区间,按位异或之后的值,的某一位,是否为 1 1 1。只需要考虑这个区间内的这一位的 1 1 1 的个数是奇数个还是偶数个。
也可以考虑 x o r xor xor 数组 a n s + ( x o r r ⊕ x o r l − 1 ) ans + (xor_r \oplus xor_{l-1}) ans+(xorrxorl1) ,按位考虑,某一位如果想被累计到答案里,那么 x o r r xor_r xorr 的这一位和 x o r l − 1 xor_{l-1} xorl1 的这一位,不相同。所以可以考虑把 x o r xor xor 拆位,如果当前这一位是 1 1 1,那么就考虑它前面这一位是 0 0 0 的情况有多少个,反之同理。

代码

#include<bits/stdc++.h>
using namespace std;
int b[305][305],c[305],sum[305];
int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n,m;
	cin>>n>>m; 
	long long cnt=0ll;
	for(int i=1; i<=n; i++){
		for(int j=1; j<=m; j++){
			cin>>b[i][j];
		}
	}
	long long ans=0;
	for(int u=1; u<=n; u++){
	    memset(c,0,sizeof c);
	    memset(sum,0,sizeof sum);
	    for(int d=u;d<=n; d++){
	        for(int j=1; j<=m; j++){
	            c[j]^=b[d][j];
	            sum[j]=c[j]^sum[j-1];
	        }
	        for(int p=0;p<10;p++){
	            int cnt[2]={1,0};
    	        for(int j=1; j<=m; j++){
    	            int t=(sum[j]>>p)&1;
    	            ans+=(1<<p)*cnt[t^1];
    	            cnt[t]++;
    	        }    
	        }
	    }
	}
	cout<<ans<<"\n";
	return 0;
}

T4

题面

在这里插入图片描述

思路

具体看代码中的注释

代码

#include<bits/stdc++.h>
using namespace std;
int a[1000005],b[1000005],cntb[15];
__int128 res[15],vis[15],cnt;
void print(__int128 ans){
	if(ans==0) return;
	print(ans/10);
	putchar(ans%10+'0');
}
int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n,m,p;
	cin>>n>>m>>p;
	for(int i=1; i<=n; i++) cin>>a[i];
	for(int i=1; i<=m; i++) cin>>b[i],cntb[b[i]]++;
	if(p==1){
		cout<<0<<"\n";
		return 0;
	}
	for(int k=0;k<p;k++){
	    memset(vis,0,sizeof vis);
	    for(int i=1; i<=m; i++){
    	    for(int j=b[i]+1; j<=p-1; j++){
    	        res[k]+=vis[j];//$res_k$ 表示 $b$ 数组加上 $k$ 后,逆序对的数量
    	    }
    	    vis[b[i]]++;
    	    b[i]=(b[i]+1)%p;
    	}
	}
	memset(vis,0,sizeof vis);//$vis$ 数组统计之前块中,每个数的出现次数
	for(int i=1; i<=n; i++){
	    cnt+=res[a[i]];//统计块内逆序对的数量
	    for(int k=0;k<p;k++){//遍历 $b$ 中所有数字的取值
	        for(int j=(a[i]+k)%p+1; j<p;j++){
	            cnt+=cntb[k]*vis[j];//$b$ 序列中,$k$ 的数量,乘以之前块中比 $(a_i+k)\bmod p$ 大的数字个数
	        }
	    }
	    for(int k=0;k<p;k++){//遍历 $b$ 中所有数字的取值
	        vis[(a[i]+k)%p]+=cntb[k];//记录数量。
	    }
	}
	print(cnt);
	return 0;
}

请关注作者的 B 站,谢谢~链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Programming_Konjac

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值