Codeforces Round 899 (Div. 2)题解记录

题目链接: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

思路:先变成字符串型,然后分别暴力出各自数组变成顺序数组的次数,最后综合分析即可

posted @ 2024-10-13 20:38  长皆  阅读(9)  评论(0编辑  收藏  举报