Codeforces Round 899 (Div. 2)題解記錄

长皆發表於2024-10-13

題目連結:https://codeforces.com/contest/1882

A. Increasing Sequence

從1開始慢慢和\(a[i]\)的所有值比較,注意最後一個位置特判下

#include<iostream>
#include<string.h>
#include<map>
#include<vector>
#include<set>
#include<unordered_set>
#include<stack>
#include<queue>
#include<algorithm>
#include<time.h>
#include<random>
using namespace std;
typedef long long ll;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
			ans = ans%mod*(x%mod)%mod;
		x = x%mod*(x%mod)%mod;
		y >>= 1;
	}
	return ans%mod%mod;
}
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
		ll n;
		cin>>n;
		ll ans=1;
		for(ll i=1;i<=n;i++)
		{
			ll x;
			cin>>x;
			if(i==n)
			{
				if(ans==x)
				ans++;
				break;
			}
			if(x==ans)
			{
				ans+=2;
				continue;
			}
			ans++;
		}
		cout<<ans<<endl;
	}
}

B. Sets and Union

資料範圍小,考慮暴力,用總集試著刪除每一個數即可

#include<iostream>
#include<string.h>
#include<map>
#include<vector>
#include<set>
#include<unordered_set>
#include<stack>
#include<queue>
#include<algorithm>
#include<time.h>
#include<random>
using namespace std;
typedef long long ll;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
			ans = ans%mod*(x%mod)%mod;
		x = x%mod*(x%mod)%mod;
		y >>= 1;
	}
	return ans%mod%mod;
}
ll a[600];
ll b[600];
set<ll>q[60];
vector<ll>g[60];
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
		for(ll i=1;i<=50;i++)a[i]=0,b[i]=0,q[i].clear(),g[i].clear();
		ll n;
		cin>>n;
		for(ll i=1;i<=n;i++)
		{
			ll x;
			cin>>x;
			for(ll j=1;j<=x;j++)
			{
				ll y;cin>>y;
				g[i].push_back(y);
				q[y].insert(i);
				a[y]++;
			}
		}
		//cout<<99<<endl;
		ll ans=0;
		for(ll i=1;i<=50;i++)
		{
			if(q[i].size()==0)continue;
			//cout<<99<<endl;
			ll cnt=0;
			for(ll k=1;k<=50;k++)
			{
				b[k]=0;
			}
			for(auto j:q[i])//模擬每個元素刪除
			{
				for(auto k:g[j])
				{
					b[k]--;
				}
			}
				//cout<<99<<endl;
			for(ll j=1;j<=50;j++)
			{
				b[j]+=a[j];
				if(b[j]>0)cnt++;
			}
			ans=max(ans,cnt);
		}
		cout<<ans<<endl;
	}
}

C. Card Game

從右往左拿正數就是最佳選擇,然後考慮下從左往右在正數出現前是否偶數位有<=0的數,或者找一個使總價值消耗最小的數

#include<iostream>
#include<string.h>
#include<map>
#include<vector>
#include<set>
#include<unordered_set>
#include<stack>
#include<queue>
#include<algorithm>
#include<time.h>
#include<random>
using namespace std;
typedef long long ll;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
			ans = ans%mod*(x%mod)%mod;
		x = x%mod*(x%mod)%mod;
		y >>= 1;
	}
	return ans%mod%mod;
}
ll a[250000];
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
		ll n;
		cin>>n;
		ll ans=0;
		for(ll i=1;i<=n;i++)
		{
			cin>>a[i];
			if(a[i]>0)
			ans+=a[i];
		}
		if(ans==0)
		{
			cout<<0<<endl;
			continue;
		}
		ll wz=0;
		for(ll i=1;i<=n;i++)
		{
			if(a[i]>0)
			{
				wz=i;
				break;
			}
		}
		if(wz%2==1)
		{
			cout<<ans<<endl;
			continue;
		}
		ll u=-999999999999;
		ll pd=0;
		for(ll i=1;i<=wz-1;i++)
		{
			if(a[i]<0&&i%2==0)
			{
				pd=1;
				break;
			}
			u=max(u,a[i]);
		}
		if(pd)
		{
			cout<<ans<<endl;
		}
		else
		{
			u=max(u,-a[wz]);
			cout<<ans+u<<endl;
		}
	}
}

D. Tree XOR

子樹變成根是最佳選擇,然後逐層往上就有解了。
資料範圍大,一個個列舉不現實,考慮轉移關係,從一個根節點到另一個根節點的變換,要考慮一個是要變的,一個本來不要變後面變了的

#include<iostream>
#include<string.h>
#include<map>
#include<vector>
#include<set>
#include<unordered_set>
#include<stack>
#include<queue>
#include<algorithm>
#include<time.h>
#include<random>
using namespace std;
typedef long long ll;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
			ans = ans%mod*(x%mod)%mod;
		x = x%mod*(x%mod)%mod;
		y >>= 1;
	}
	return ans%mod%mod;
}
ll a[250000];
vector<ll>g[250000];
ll sz[250000];
ll b[250000];
ll ans=0;
void dfs(ll x,ll fa)
{
	sz[x]=1;
	for(auto j:g[x])
	{
		if(j==fa)continue;
		dfs(j,x);
		sz[x]+=sz[j];
	}
//	cout<<x<<" "<<sz[x]<<endl;
	if(x!=1)
	{
		ans+=(a[fa]^a[x])*sz[x];
	}
}
ll n;
void df(ll x,ll fa,ll zy,ll fs)
{
	//sz[x]+=sz[fa];//中心轉移
	if(x!=1)
	{
		fs-=(a[x]^zy)*sz[x];//最後一步不轉化了
		fs+=(a[x]^zy)*(n-sz[x]);
		b[x]=fs;
	}
    for(auto j:g[x])
	{
		if(j==fa)continue;
		df(j,x,a[x],fs);
	}
}
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
		ans=0;
		cin>>n;
		for(ll i=1;i<=n;i++)cin>>a[i],g[i].clear();
		for(ll i=1;i<n;i++)
		{
			ll l,r;
			cin>>l>>r;
			g[l].push_back(r);
			g[r].push_back(l);
		}
		vector<ll>g;
		dfs(1,-1);
		b[1]=ans;
		df(1,-1,0,ans);
		for(ll i=1;i<=n;i++)cout<<b[i]<<" ";
		cout<<endl;
	}
}

E1

思路:先變成字串型,然後分別暴力出各自陣列變成順序陣列的次數,最後綜合分析即可

相關文章