23.12.24周报(赛后康复训练)

星期一:

市赛打铁后的第一天。

早八数据结构讲了快排,老实说我到现在也确实不是很清楚快排咋写,然后回机房看了下。

下午继续手搓快排,搓完开始做题。从今天开始,准备每天做三道题,构造,图,dp各一道。

手搓快排:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=2e5+10,M=1e5+10;
const int mod=998244353;

int n;
int a[N];
int q(int l,int r){
	int i=l,j=r;
	int p=a[l];
	while(i<j){
		while(a[j]>=p && i<j) j--;
		while(a[i]<=p && i<j) i++;
		swap(a[i],a[j]);
	}
	swap(a[l],a[i]);
	return i;
}
void ssort(int l,int r){
	if(l>=r) return ;
	int mid=q(l,r);
	ssort(l,mid-1);
	ssort(mid+1,r);
}
void solve(){
	cin >> n;
	for(int i=1;i<=n;i++) cin >> a[i];
	ssort(1,n);
	for(int i=1;i<=n;i++) cout << a[i] << " ";
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _=1;
//	cin >> _;
	while(_--) solve();
	return 0;
}
//make it count
//开ll plz

每日三题之构造:

题意:自行理解

思路:感觉也不像构造,开个bool数组模拟一下存二进制位就可以了。

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=2e5+10,M=1e5+10;
const int mod=998244353;

int n;
int m,k;
int x[1010],xx;
bool vi[30];
ll ans;
bool check(int num){
	int cnt=0;
	for(int i=n-1;i>=0;i--){
		int tmp=pow(2,i);
		if(num>=tmp){
			num-=tmp;
			if(!vi[i]) cnt++;
		}else{
			if(vi[i]) cnt++;
		}
	}
	return cnt<=k;
}
void solve(){
	cin >> n >> m >> k;
	for(int i=1;i<=m;i++){
		cin >> x[i];
	}
	cin >> xx;
	for(int i=n-1;i>=0;i--){
		int tmp=pow(2,i);
		if(xx>=tmp) xx-=tmp,vi[i]=1;
	}
//	for(int i=n-1;i>=0;i--) cout << vi[i] << " ";
	for(int i=1;i<=m;i++){
		if(check(x[i])) ans++;
	}
	cout << ans;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _=1;
//	cin >> _;
	while(_--) solve();
	return 0;
}
//make it count
//开ll plz

然后做了点标签为dp和图的题,cf上的标签贴的好随意。

星期二:

给23年新生赛验题做了道数论:

题意:如图

思路:无需多言

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=1e6+10;
ll n;
ll k;
int cnt;
void solve(){
	cin >> k >> n;
	int tmp=0;
	while((n/k)>(tmp/k)){
		int tn=n;
		n+=n/k-tmp/k;
		tmp=tn;
	}
	cout << n << "\n";
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _=1;
	cin >> _;
	while(_--) solve();
	return 0;
}
//make it count
//开ll plz

昨晚的div2的c题,没做出来,wa5,今下午来补了:

题意:自行理解

思路:我开始封装了check函数用来判断yes和no,没封好,一直wa5,如下

bool check(){
	int tmp[40]={0};
	for(int i=0;i<=39;i++) tmp[i]=bi[i];
//	for(int i=4;i>=0;i--) cout << tmp[i] << " ";
//	cout << "\n";
	for(int i=29;i>=0;i--){
		if(ne[i] && tmp[i]) continue;
		if(ne[i] && !tmp[i]){
			bool iff=0;
			for(int j=i;j>=0;j--){
				if(tmp[j]>=qpow(i-j)){
					tmp[j]-=qpow(i-j);
					iff=1; break;
				}
			}
			if(!iff) return 0;
		}
	}
	return 1;
}

后来改成用现有的binary数组直接判断,就过了。。代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=2e5+10,M=1e5+10;
const int mod=998244353;

int n;
int m;
int bi[40],ne[40];
int qpow(int n){
	if(n==0) return 1;
	if(n==1) return 2;
	int s=qpow(n/2);
	s=s*s;
	if(n&1) s=s*2;
	return s;
}
void solve(){
	cin >> m;
	while(m--){
		int t,v;
		cin >> t >> v;
		if(t==1){
			bi[v]++;
		}else{
			for(int i=29;i>=0;i--){
				if(bi[i] && v){
					int cnt=bi[i];
					v-=min(v/qpow(i),cnt)*qpow(i);
				}
			}
			v?cout << "NO\n":cout << "YES\n";
		}
	}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _=1;
//	cin >> _;
	while(_--) solve();
	return 0;
}
//make it count
//开ll plz

星期三:

昨晚div3的C题被hack了(tle),难受啊

题意:自行理解

思路:刚开始见到又以为是dp,以为就在这里结束了,结果冷静下来发现是枚举前缀和优化

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=2e5+10,M=1e5+10;
const int mod=998244353;

int n;
int k;
int a[N],b[N];
int sum[N],ma[N];
ll ans;
void solve(){
	ans=0;
	memset(ma,0,sizeof ma);
	memset(sum,0,sizeof sum);
	cin >> n >> k;
	for(int i=1;i<=n;i++){
		cin >> a[i];
		sum[i]+=a[i]+sum[i-1];
	}
	for(int i=1;i<=n;i++){
		cin >> b[i];
		ma[i]=max(ma[i-1],b[i]);
	}
	for(int i=1,j=min(n,k);i<=j;i++){ //j=min(n,k)是关键,没加这句会被tle
		ans=max(1ll*sum[i]+(k-i)*ma[i],ans);
	}
	cout << ans << "\n";
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int O_o=1;
	cin >> O_o;
	while(O_o--) solve();
	return 0;
}
//make it count
//开ll plz

晚上看了下单调队列,为多重背包究极版做准备。

星期四:

重回绿名,无需多言。23年还有4场cf可以打,运气好()说不定能上个青,冲冲冲。

看了一晚上多重背包单调队列优化,没看懂。

星期五:

早上看了会,下午看了会,看的似懂非懂,决定先放着,以后dp熟悉了再来看。

星期六:

办完23级新生比赛,晚上公款下馆子。

星期天:

昨晚div1+div2被拿下了,a题签到因为各种失误耽误了一个多小时,第二题思路有了没实现出来(也来不及实现了),一题尾掉回newbie。。

补下B题:

题意:自行理解

思路:刚开始想到俩特例,奇偶同时存在k为2,和本就符合条件k为1e18。后来找了会规律感觉可以用二进制做,代码没调出来。今下午来试了试,发现long long最多只能装2^62,装63会超,得用unsigned long long,怪不得昨晚没调出来。

改成unsigned long long 后,一发a,代码如下:(这就是cf的二进制啊,真是00又11啊)

#include <bits/stdc++.h>
using namespace std;
using ll=unsigned long long;
using PII=pair<int,int>;

const int N=3e4+10,M=1e5+10;
const int mod=998244353;

int n;
bool bi[110][80];
ll qpow(int n){
	if(n==0) return 1;
	if(n==1) return 2;
	ll s=qpow(n/2);
	s=s*s;
	if(n&1) s=s*2;
	return s;
}
void solve(){
	memset(bi,0,sizeof bi);
	cin >> n;
	for(int i=1;i<=n;i++){
		ll a;
		cin >> a;
		for(int j=63;j>=0;j--){
			ll tmp=qpow(j);
			if(a>=tmp) a-=tmp,bi[i][j]=1;
		}
	}
	for(int i=0;i<=63;i++){
		bool s=bi[1][i];
		for(int j=2;j<=n;j++){
			if(bi[j][i]^s){cout << qpow(i+1) << "\n"; return ;}
		}
	}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int O_o=1;
	cin >> O_o;
	while(O_o--) solve();
	return 0;
}
//make it count
//开ll plz

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值