『模拟赛』暑假集训CSP提高模拟4
Rank
一次比一次烂了,鉴定为不写模拟赛记录导致的。
A. White and Black
被自己误导了,导致菊花和链的部分分没拿到。
经验++
对于每个点的父节点若有
Subtask 越来越不好判了www
思路
首先比较易得的是,不会出现无解的情况:因为任意一个节点我们都可以通过先翻转自身再翻转所有子节点的方式将其单独翻转。
其次,按暴力的方法找到思路:对于一个点集
考虑到要求反转的点的数量很小,我们尝试着枚举这些点求解。
读入时标记这些点,枚举时判断其父节点是否被标记,若不是意味着我们需要翻转该点,若是则说明他已经被翻转过。我们若仅翻转枚举的该点,那么对答案的贡献应为其子节点的数量之和加上
简单画个图模拟一下,发现这样做会产生很多次无用操作。我们在翻转一个被标记的节点时,默认将其子节点再次翻回来,也就是上述的操作;如果一个点的父节点被标记,那么此时该点已经被翻转了两次,我们不用再次翻转该节点,且是要在操作其父节点时不将其二次翻转,这样才能得到最优操作次数。因此在遇到父节点被标记的节点时,我们要将答案减去
细节处理
这道题搬到我们题库上只给了 memset
要快很多。
数据的点集中会有父节点后被标记的情况,所以不能边读边做,要把点集先存下来。
Code:
#include<bits/stdc++.h>
const int Ratio=0;
const int N=2e5+5;
int n,m,tot,ans;
int fx[N],son[N];
int tag[N],s[N];
namespace Wisadel
{
short main()
{
scanf("%d%d",&n,&m);
for(int i=2;i<=n;i++)
scanf("%d",&fx[i]),son[fx[i]]++;
for(int i=1;i<=m;i++)
{
scanf("%d",&tot);ans=0;
for(int j=1;j<=tot;j++)
scanf("%d",&s[j]),tag[s[j]]=1;
for(int j=1;j<=tot;j++)
{
if(tag[fx[s[j]]]) ans--;
else ans++;
ans+=son[s[j]];
}
printf("%d\n",ans);
for(int j=1;j<=tot;j++) tag[s[j]]=0;
}
return Ratio;
}
}
int main(){return Wisadel::main();}
B. White and White
原题C3 放前两个没什么意义。
赛时想到了用和模上
思路
赛时只想出了
首先,按定义
下面证明直接搬了。
Code:
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
char ch=getchar();lx x=0,f=1;
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
return x*f;
}
#undef lx
#define qr qr()
const int Ratio=0;
const int N=5e5+1;
int n,k,p;
int a[N],sum[N],f[N][101],op[2][101];
namespace Wisadel
{
short main()
{
n=qr,k=qr,p=qr;
fo(i,1,n)
a[i]=qr%p,sum[i]=(sum[i-1]+a[i])%p;
memset(f,0x3f,sizeof f);
f[0][0]=0;
fo(i,1,n)
{
int fla=(i&1)^1;
fo(j,1,k)
f[i][j]=min(f[i][j],f[op[fla][j-1]][j-1]+((sum[i]-sum[op[fla][j-1]])%p+p)%p);
fo(j,0,k)
{
op[i&1][j]=op[fla][j];
if(f[i][j]<f[op[i&1][j]][j]) op[i&1][j]=i;
}
}
printf("%d\n",f[n][k]);
return Ratio;
}
}
int main(){return Wisadel::main();}
C. Black and Black
很神的构造题,赛时想的跟题解差不多,但没时间也没自信考场打出这么复杂的解法。
大体思路是对于每个确定的序列,都能使前缀和后缀同时加或减一个数,加减取决于前缀后缀的正负。我们可以通过调整来实现积的和为零,若无法实现即为无解。
Code:
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
typedef long long ll;
inline int qr()
{
char ch=getchar();int x=0,f=1;
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
return x*f;
}
#define qr qr()
const int Ratio=0;
const int N=2e5+1;
int n,k,p;
int a[N];
int pf,pz,sf,sz;
ll ans[N],sum;
namespace Wisadel
{
void Wgetqianhouzhui()
{
int cnt=0;
fo(i,1,n)
{
cnt+=a[i];// 记录前缀
if(!pf&&cnt<0) pf=i;
// 前缀和为负 记录
if(!pz&&cnt>0) pz=i;
// 为正同理
if(pz&&pf) break;
}
cnt=0;
fu(i,n,1)
{
cnt+=a[i];// 记录后缀
if(!sf&&cnt<0) sf=i;
if(!sz&&cnt>0) sz=i;
if(sz&&sf) break;
}
}
short main()
{
n=qr;
fo(i,1,n)
{
a[i]=qr;
ans[i]=i,sum+=a[i]*ans[i];
// 赋初值
}
Wgetqianhouzhui();
int pre=0,suf=0;
if(sum<0) sum=-sum,pre=pf,suf=sz;
else if(sum>0) pre=pz,suf=sf;
// 首先 前缀只能统一减小,后缀只能统一增大
// 关键 如果当前和为负,我们需要往大了调整
// 方案为负的前缀统一缩小 或 正的后缀统一增大
// 和为正,就要调小
// 方案为正的前缀缩小 或 负的后缀增大
if(sum)
{
if(pre) fo(i,1,pre) ans[i]-=sum;
else if(suf) fo(i,1,suf) ans[i]+=sum;
else
{
printf("No\n");
return Ratio;
}
}
printf("Yes\n");
fo(i,1,n) printf("%lld ",ans[i]);
return Ratio;
}
}
int main(){return Wisadel::main();}
D. Black and White
看了第一篇括号序列的题解,真的好逆天啊。虽然很复杂但其实如果深刻理解的话每一步都是很关键的。通过转化成括号序列来简化(?)问题有时候确实好用。
Code:
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
char ch=getchar();lx x=0,f=1;
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
return x*f;
}
#undef lx
#define qr qr()
const int Ratio=0;
const int N=1e5+5,M=5e5+5;
int n,ans,num;
int hh[N],ne[N<<1],to[N<<1],cnt;
int st[N*3],tot,dfn[N];
bool yz[N];
struct rmm
{
int a,b,p1,p2,s1,s2,dis;
}t[M<<2];
namespace Wisadel
{
void Wadd(int u,int v)
{
to[++cnt]=v;
ne[cnt]=hh[u];
hh[u]=cnt;
}
void Wdfs(int u,int fa)
{
st[++tot]=-1;
st[++tot]=u,dfn[u]=tot;
for(int i=hh[u];i!=-1;i=ne[i])
{
int v=to[i];
if(v==fa) continue;
Wdfs(v,u);
}
st[++tot]=-2;
}
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)
void Wpush(int rt,int x)
{
t[rt].a=t[rt].b=0;
t[rt].p1=t[rt].p2=t[rt].s1=t[rt].s2=t[rt].dis=-1e9;
if(st[x]==-1) t[rt].b=1;
else if(st[x]==-2) t[rt].a=1;
else if(!yz[st[x]]) t[rt].p1=t[rt].p2=t[rt].s1=t[rt].s2=0;
}
void Wpushup(int rt)
{
if(t[ls].b>t[rs].a)
t[rt].a=t[ls].a,t[rt].b=t[ls].b+t[rs].b-t[rs].a;
else
t[rt].a=t[ls].a+t[rs].a-t[ls].b,t[rt].b=t[rs].b;
t[rt].p1=max(t[ls].p1,max(t[rs].p1+t[ls].a-t[ls].b,t[rs].p2+t[ls].a+t[ls].b));
t[rt].p2=max(t[ls].p2,t[rs].p2-t[ls].a+t[ls].b);
t[rt].s1=max(t[rs].s1,max(t[ls].s1-t[rs].a+t[rs].b,t[ls].s2+t[rs].a+t[rs].b));
t[rt].s2=max(t[rs].s2,t[ls].s2+t[rs].a-t[rs].b);
t[rt].dis=max(max(t[ls].s1+t[rs].p2,t[ls].s2+t[rs].p1),max(t[ls].dis,t[rs].dis));
}
void Wbuild(int rt,int l,int r)
{
if(l==r)
{
Wpush(rt,l);
return;
}
Wbuild(ls,l,mid),Wbuild(rs,mid+1,r);
Wpushup(rt);
}
void Wupd(int rt,int l,int r,int x)
{
if(l==r)
{
Wpush(rt,l);
return;
}
if(x<=mid) Wupd(ls,l,mid,x);
else Wupd(rs,mid+1,r,x);
Wpushup(rt);
}
short main()
{
// freopen("1.in","r",stdin),freopen("1.out","w",stdout);
memset(hh,-1,sizeof hh);
n=qr;
fo(i,1,n-1)
{
int a=qr,b=qr;
Wadd(a,b),Wadd(b,a);
}
Wdfs(1,0);
num=n;
Wbuild(1,1,tot);
int q=qr;
fo(i,1,q)
{
char op;cin>>op;int x;
if(op=='C') x=qr,num+=yz[x]?1:-1,yz[x]^=1,Wupd(1,1,tot,dfn[x]);
else if(num==0) printf("-1\n");
else if(num==1) printf("0\n");
else printf("%d\n",t[1].dis);
}
return Ratio;
}
}
int main(){return Wisadel::main();}
末
这场虽然发挥得不是很好,但感觉收获是比这几天都要多的,保持状态,继续加油!
朋友们,愿你任何时候都拥有勇往直前的决心和披荆斩棘的勇气。——雷军
完结撒花~
晚来的 OIer 有图看。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探