8月月賽I題解


Div 2

Div 1

Div2 A

題目

建議評分:橙。

我的做法:不管,這是一道高精題(確信,使用高精模板即可。

時間復雜度\(O(k+\lg x)\),空間復雜度\(O(k)\)

代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
const ll SIZE=505;
ll x,k,ans[SIZE];
void print(ll *a){
	ll i;
	for(i=SIZE-1;i>0;i--) if(a[i]>0) break;
	for(;i>=0;i--) cout<<a[i]; cout<<endl;
}
int main(){
	cin>>x>>k;
	ans[x]=1;
	ans[0]+=k;
	for(ll i=1;ans[i-1]>=10;i++){
		ans[i]+=ans[i-1]/10;
		ans[i-1]%=10;
	}
	print(ans);
	return 0;
}

Div2 B

題目

建議評分:黃。

結論題。

我們有如下幾個結論:

  • 對於任意給定的\(a,b\),我們可以用一次\(1\)操作和一次\(2\)操作變成0。

證明:我們可以先用\(1\)操作,使得一個數變成\(0\),另一個數變成一個非負數,然后再用\(2\)操作,將\(0\)乘上\(x\),另一個數除以\(x\),只要取\(x\)充分大可以全為\(0\)

  • 對於任意給定的\(a,b\),我們可以用兩次\(2\)操作變成0。

證明:我們可以先用\(2\)操作,使得一個數變成\(0\),另一個數變成一個非負數,然后再用\(2\)操作,將\(0\)乘上\(x\),另一個數除以\(x\),只要取\(x\)充分大可以全為\(0\)

  • \(a=b\)時,可以只用一次\(1\)操作變成0。

證明:顯然。

  • \(a=0\)\(b=0\)時,可以只用一次\(2\)操作變成0.

證明:使用一次\(2\)操作,將\(0\)乘上\(x\),另一個數除以\(x\),只要取\(x\)充分大可以全為\(0\)

  • \(a=b=0\)時,不需要任何操作。

證明:顯然。

時空復雜度均為\(O(1)\)

代碼:

#include<bits/stdc++.h>
using namespace std;
int a,b,c,d,ans;
int main(){
	cin>>a>>b>>c>>d;
	ans=min(c+d,d*2);
	if(a==0&&b==0)ans=0;
	if(a==0||b==0)ans=min(ans,d);
	if(a==b)ans=min(ans,c);
	cout<<ans<<endl;
	return 0;
}

Div1 A

題目

建議評分:藍。

考慮貪心,我們可以發現對於每一個二進制位來說,我們更希望他是\(1\),即使后面全都是\(0\)

於是我們預處理出每一位上\(0\)的個數和\(1\)的個數,在查詢的時候我們只要考慮如果這一位填\(1\)會不會導致后面無法填,這顯然可以用前綴和維護一下。

具體地,令\(sum_{i,j}\)表示\(x\)二進制下的第\(i\)位填\(j\)的貢獻,\(min_i\)表示只考慮前\(i\)位的情況下,\(\sum(a_i\operatorname{xor}x)\)的最小值。

這里\(sum_{i,j}\)可以暴力預處理,\(min_i\)就是\(\min\{sum_{i,0},sum_{i,1}\}\)的前綴和。

考慮從第一位開始往后填,設填到第\(i\)位時的要求為\(m\),則只要\(m\ge min_{i-1}+sum_{i,0}\),就可以填\(1\),否則填\(0\)

時間復雜度\(O((n+q)\log m)\),空間復雜度\(O(n+\log m)\)

代碼:

#include<bits/stdc++.h>
using namespace std;
typedef __int128 ll;
const ll N=100005,M=50;
ll n,q,m,a[N],sum[M][2],mi[M];
inline int getbit(ll x,int p){return (x&(1LL<<p))>>p;}
char ss[1<<17],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<17,stdin),A==B)?-1:*A++;}
inline void read(ll&x){
    x=0;char s=gc();
    while(!isdigit(s))s=gc();
    while(isdigit(s))x=x*10+(s^'0'),s=gc();
}
void print(ll x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)print(x/10);
    putchar(x%10+'0');
}
int main(){
	read(n);
	for(ll i=1;i<=n;i++)read(a[i]);
	for(ll i=0;i<M;i++)
		for(ll j=1;j<=n;j++)
			sum[i][getbit(a[j],i)]+=(1LL<<i);
	mi[0]=min(sum[0][0],sum[0][1]);
	for(ll i=1;i<M;i++)mi[i]=mi[i-1]+min(sum[i][0],sum[i][1]);
	for(read(q);q--;){
		read(m);
		if(m<mi[M-1]){puts("-1");continue;}
		ll ans=0;
		for(ll i=M-1;i>=0;i--){
			if(i==0&&m>=sum[i][0]||i>0&&m>=mi[i-1]+sum[i][0])ans|=(1LL<<i),m-=sum[i][0];
			else m-=sum[i][1];
		}
		print(ans),puts("");
	}
	return 0;
}

Div1 B

暫時還不會。

Div1 C

暫時還不會。

Div1 D

暫時還不會。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM