星期一:
市赛打铁后的第一天。
早八数据结构讲了快排,老实说我到现在也确实不是很清楚快排咋写,然后回机房看了下。
下午继续手搓快排,搓完开始做题。从今天开始,准备每天做三道题,构造,图,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