Ethflow Round 1 (Codeforces Round 1001, Div. 1 + Div. 2)(A~E1)题解记录
好久没写codeforces题解,这次E1赛后才做出来,为了方便点,先不把题目挂出来了
比赛链接:https://codeforces.com/contest/2062
A.String
思路:显然可以发现,选择方法形如10101,这种其实是最佳的,然后可以发现这种变成全0的次数等于其1的个数,故归纳一下,本题答案就是对应字符串1的个数
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
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 gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l,r;
bool operator<(const s&a)
{
}
};
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
string f;
cin>>f;
ll cnt=0;
for(ll i=0;i<f.size();i++)
{
cnt+=(f[i]=='1');
}
cout<<cnt<<endl;
}
}
B.Clockwork
思路:考虑最坏情况即可,即从一个点出发,从该点出发前往最远端回来,如果回来之前变为0,则一定无解。如果都满足,显然移动周期内都可以过所有点一遍的
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
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 gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l,r;
bool operator<(const s&a)
{
}
};
ll a[5450000];
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
ll pd=0;
for(ll i=1;i<=n;i++)
{
ll x;
cin>>x;
if((i-1)*2>=x||(n-i)*2>=x)pd=1;
}
if(pd)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
}
C.Cirno and Operations
思路:只有两种操作,其实第二种变成差分数组,反转之前和之后,值只有正负之分,绝对值是一样的,数据范围小,暴力枚举即可,其实每次取个最大abs(
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
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 gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l,r;
bool operator<(const s&a)
{
}
};
ll a[5450000];
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
ll ans=-1e18;
ll sum=0;
for(ll i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
ans=sum;
ll l=1,r=n;
while(1)
{
sum=0;
if(l==r)break;
if(a[r]-a[l]>=0)
{
for(ll i=r;i>=l+1;i--)
{
a[i]=a[i]-a[i-1];
}
l++;
}
else
{
for(ll i=l;i<=(l+r)>>1;i++)
{
swap(a[i],a[r-i+l]);
}
}
for(ll i=l;i<=r;i++)
{
sum+=a[i];
}
ans=max(ans,sum);
}
cout<<ans<<endl;
}
}
D.Balanced Tree
思路:本题从树的角度去考虑,如果儿子中的最大值小于等于父亲的值,其实没有必要修改父亲的,但是得传递修改值;如果父亲的值小于儿子的值,其修改值将是所有大于父亲的儿子的值-父亲的值之差的和。所以我们可以发现一个节点的值不能太大也不能太小,所以我们尽量往儿子中的最大值去靠即可(越大,答案越不优;越小,答案只会大于等于最优答案),然后分情况改变下修改值即可。
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
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 gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l,r;
bool operator<(const s&a)
{
}
};
ll a[5450000];
vector<ll>g[250000];
ll ans=0;
map<ll,pair<ll,ll>>z;
ll dfs(ll x,ll f)
{
ll xg=0;
vector<pair<ll,ll>>k;
ll l=z[x].first;
ll r=z[x].second;
ll u=0;
ll z=0;
for(auto j:g[x])
{
if(j==f)continue;
xg+=dfs(j,x);
u=max(u,a[j]);
if(a[j]>=r)z+=a[j]-r;
}
if(u>=l&&u<=r)
{
a[x]=u;
return xg;
}
else if(u<=l)
{
a[x]=l;
return xg;
}
else
{
a[x]=r;
return xg+z;
}
};
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
z.clear();
ans=0;
ll n;
cin>>n;
for(ll i=1;i<=n;i++)
{
g[i].clear();
ll l,r;
cin>>l>>r;
z[i]={l,r};
}
for(ll i=1;i<n;i++)
{
ll l,r;
cin>>l>>r;
g[l].push_back(r);
g[r].push_back(l);
}
cout<<dfs(1,0)+a[1]<<endl;
}
}
E1.The Game (Easy Version)
思路:没往LCA去想,但是这道题LCA好做,可能答案也是LCA?满足LCA要求后,我们先进行排序,优先值,其次是深度,这个很重要。最大值的所有点不考虑,如果倒序遍历过程中,该值和上一个值不相同,我们就去遍历上一个所有点,如果该点和上一个值点的所有点LCA都是该点则继续,否则解就是该点,break;如果相同,由于进行深度排序了,此时该点的深度比他小,如果该点和上一个点的LCA,只要不是该点,则该点即是答案,break,否则重复上述步骤即可,显然不会TLE
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
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 gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll dep[450000];
struct s
{
ll l, r;
bool operator<(const s& a)
{
if (r != a.r)
return r < a.r;
else return dep[l] < dep[a.l];
}
}p[405000];
ll a[450000];
vector<ll>g[450000];
vector<ll>k[450000];
ll fa[450000][36];
ll lca(ll x, ll y)
{
if (dep[x] < dep[y])swap(x, y);
ll dis = dep[x] - dep[y];
for (ll i = 30; i >= 0; i--)
{
if ((1ll << i) <= dis)
{
dis -= 1ll << i;
x = fa[x][i];
}
}
if (x == y)
return x;
for (ll i = 30; i >= 0; i--)
{
if (fa[x][i] != fa[y][i])x = fa[x][i], y = fa[y][i];
}
return fa[x][0];
}
void dfs(ll x, ll f)
{
dep[x] = dep[f] + 1;
fa[x][0] = f;
for (ll i = 1; i <= 31; i++)
{
fa[x][i] = fa[fa[x][i - 1]][i - 1];
}
for (auto j : g[x])
{
if (j == f)continue;
dfs(j, x);
}
}
int main()
{
fio();
ll t;
cin >> t;
while (t--)
{
ll n;
cin >> n;
for (ll i = 1; i <= n; i++)
{
cin >> a[i];
p[i].l = i;
k[i].clear();
p[i].r = a[i];
g[i].clear();
}
for (ll i = 1; i <= n; i++)
{
k[a[i]].push_back(i);
}
for (ll i = 1; i < n; i++)
{
ll l, r;
cin >> l >> r;
g[l].push_back(r);
g[r].push_back(l);
}
dfs(1, 0);
sort(p + 1, p + 1 + n);
ll ans = 0;
ll flag = p[n].r;
//for(ll i=1;i<=n;i++)cout<<p[i].l<<endl;
for (ll i = n - 1; i >= 1; i--)
{
//cout<<p[i].l<<endl;
if (p[i].r == p[n].r)continue;
if (flag != p[i].r)
{
for (auto j : k[flag])
{
//if (flag == 3)cout << j << endl;
ll u = lca(p[i].l, j);
if (u == p[i].l)continue;
else ans = p[i].l;
}
}
else if (flag == p[i].r)
{
if (lca(p[i + 1].l, p[i].l) == p[i].l)continue;
else ans = p[i].l;
}
if (ans)break;
flag = p[i].r;
}
cout << ans << endl;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】