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