2026杭电多校1
2026杭电多校第一场
总结
| 项目 | 内容 |
|---|---|
| 赛时通过 | A |
| 赛后补题 | E,F,J,D,H,L |
A.小丑牌
Tag:
贪心
题意:略
题解
注意到 \(x*y\) 的最值取到时,\(x\) 和 \(y\) 一定取到最值,分情况讨论即可
参考代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll x,y,n,m;
void solve() {
cin>>x>>y>>n>>m;
ll maxa=-1e11,mina=1e11,maxb=-1e11,minb=1e11;
for(ll i=1,u;i<=n;i++)
{
cin>>u;
maxa=max(u,maxa);
mina=min(u,mina);
}
for(ll i=1,v;i<=m;i++)
{
cin>>v;
maxb=max(v,maxb);
minb=min(v,minb);
}
ll maxx=max(x+maxa,x);
ll maxy=max(y+maxb,y);
ll minx=min(x+mina,x);
ll miny=min(y+minb,y);
cout<<max({maxx*maxy,maxy*minx,maxx*miny,miny*minx})<<"\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
ll T=1;
cin>>T;
while(T--) {
solve();
}
}
E. 摩卡数
Tag:
构造
题意 :构造字符串s使得其KMP自动机的fail树上跳跃的总次数等于给定值
题解
注意到字符只有两个时就已经可以满足题意,直接构造即可
参考代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll n;
bool check(ll x)
{
if(x*(x+1)/2<=n) return 1;
else return 0;
}
void solve()
{
cin>>n;
ll l=1,r=45000,mid;
while(l<r)
{
mid=(l+r+1)/2;
if(check(mid)) l=mid;
else r=mid-1;
}
ll len1=l+1;
ll len2=(n-l*(l+1)/2);
cout<<len1+len2<<" "<<"2"<<"\n";
for(int i=1;i<=l+1;i++) cout<<"a";
for(int i=1;i<=len2;i++) cout<<"b";
cout<<"\n";
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin>>t;
while(t--) solve();
return 0;
}
F. 开关灯
Tag:
概率期望
题意 :计算随机序列的期望
题解
这种题一般是利用期望的求和性质分解,(注意到连续段这一量是可分解的)
参考代码
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
const i64 mod=998244353;
i64 inv6;
i64 qpow(i64 a,i64 p)
{
i64 ans=1;
while(p)
{
if(p&1) ans=ans*a%mod;
a=a*a%mod;
p>>=1;
}
return ans;
}
void solve()
{
int n;
cin>>n;
vector<i64> a(n+1);
i64 sum=0;
for(int i=1;i<=n;i++) cin>>a[i],sum=(sum+a[i])%mod;
i64 ans=(a[1]+a[n])%mod*inv6%mod;
ans=(ans+1ll*(n+3)*inv6%mod*sum%mod)%mod;
cout<<ans<<"\n";
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
inv6=qpow(6,mod-2);
int t;
cin>>t;
while(t--) solve();
return 0;
}
J. 游戏
Tag:
博弈
题意 :略
题解
注意分类讨论的准确性,赛事16发wa警钟长鸣
参考代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll n,a[1000005];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
ll l=1,r=n;
if(r-l==0)
{
cout<<"NO\n";
return;
}
else if(r-l==1)
{
cout<<"YES\n";
return;
}
else
{
if(n%2==0)
{
ll sum1=0,sum2=0;
for(int i=1;i<=n/2;i++) sum1+=a[i];
for(int i=n/2+2;i<=n;i++) sum2+=a[i];
if(sum1>sum2)
{
cout<<"YES\n";
return;
}
else if(sum1<sum2)
{
cout<<"NO\n";
return;
}
else
{
ll cnt1=0,cnt2=0;
for(int i=n/2;i>=2;i--)
{
cnt1+=a[i];
cnt2+=a[n+2-i];
if(cnt1!=cnt2)
{
if(cnt1<cnt2)
{
cout<<"YES\n";
return;
}
else
{
cout<<"NO\n";
return;
}
}
}
}
}
else
{
ll sum1=0,sum2=0;
for(int i=1;i<=n/2;i++) sum1+=a[i];
for(int i=n/2+2;i<=n;i++) sum2+=a[i];
if(sum1>sum2)
{
cout<<"YES\n";
return;
}
else if(sum1<sum2)
{
cout<<"NO\n";
return;
}
else
{
ll cnt1=0,cnt2=0;
for(int i=n/2;i>=1;i--)
{
cnt1+=a[i];
cnt2+=a[n+1-i];
if(cnt1!=cnt2)
{
if(cnt1<cnt2)
{
cout<<"YES\n";
return;
}
else
{
cout<<"NO\n";
return;
}
}
}
cout<<"NO\n";
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin>>t;
while(t--) solve();
return 0;
}
D.搭积木
Tag:
贪心堆
题意 :略
题解
首先发现合并某一个和他的父亲只取决于这个连通分支的 \(a_{i}/b_{i}\) ,那么我们可以用并查集维护连通分支,从而模拟合并的过程;
参考代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,ans;
struct node{
ll a,b,fa,id;
}s[200005];
struct cmp {
bool operator()(const node& a, const node& b) {
return a.a*b.b<a.b*b.a;
}
};
struct DSU {
std::vector<ll> pa, size;
explicit DSU(ll size_) : pa(size_), size(size_, 1) {
std::iota(pa.begin(), pa.end(), 0);
}
ll find(ll x) { return pa[x] == x ? x : pa[x] = find(pa[x]); }
void unite(ll x, ll y) {
x = find(x), y = find(y);
if (x == y) return;
if (size[x] < size[y]) std::swap(x, y);
pa[y] = x;
size[x] += size[y];
}
};
void solve() {
cin>>n;
for(ll i=1;i<=n;i++){
cin>>s[i].a;
}
for(ll i=1;i<=n;i++){
cin>>s[i].b;
}
for(ll i=1;i<=n;i++){
cin>>s[i].fa;
}
for(ll i=0;i<=n;i++){
s[i].id=i;
}
priority_queue<node,vector<node>,cmp> q;
for(int i=2;i<=n;i++){
q.push(s[i]);
}
DSU k(n+1);
ans=0;
ll cnt=0;
while(cnt<n-1){
node xn=q.top();
q.pop();
if(xn.a!=s[k.find(xn.id)].a) continue;
if(xn.fa==0) continue;
cnt++;
ans+=s[k.find(xn.id)].a*s[k.find(xn.fa)].b;
node nxt={s[k.find(xn.id)].a+s[k.find(xn.fa)].a,s[k.find(xn.id)].b+s[k.find(xn.fa)].b,s[k.find(xn.fa)].fa,0};
k.unite(xn.id,xn.fa);
s[k.find(xn.id)]=nxt;
s[k.find(xn.id)].id=k.find(xn.id);
q.push(s[k.find(xn.id)]);
}
cout<<ans<<"\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
ll T=1;
cin>>T;
while(T--) {
solve();
}
}

浙公网安备 33010602011771号