点我看题

A. Hall of Fame

先把不用操作就合法的情况判掉。然后发现交换LL,RR,RL都是没用的,只有交换LR是有用的,这样可以照亮相邻的两个位置。所以我们就是要找到一个位置i,满足\(s_i=L,s_{i+1}=R\),且除了i和i+1,其他位置初始没有没被照亮的(其实这个条件必然满足)。所以随便找一个"LR"交换就行了,找不到就是无解。

时间复杂度\(O(n)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; int t,n,a[100010];
string s; int main()
{
fileio(); cin>>t;
rep(tn,t)
{
cin>>n>>s;
rep(i,n+3) a[i]=0;
int hv=0;
rep(i,n)
{
if(hv) a[i]=1;
if(s[i]=='R') hv=1;
}
hv=0;
for(int i=n-1;i>=0;--i)
{
if(hv) a[i]=1;
if(s[i]=='L') hv=1;
}
int tot=0;
rep(i,n) if(a[i]==0) ++tot;
if(tot==0) puts("0");
else
{
bool bad=true;
rep(i,n-1) if((int)(a[i]==0)+(int)(a[i+1]==0)==tot&&s[i]=='L'&&s[i+1]=='R')
{
cout<<i+1<<endl;
bad=false;break;
}
if(bad) puts("-1");
}
} termin();
}

B. MKnez's ConstructiveForces Task

首先n为偶数的时候很容易构造出解,\(1,-1,1,-1\cdots\)就行了。样例里n=3是无解,看起来奇数都是无解。但真的是这样吗?由于任意相邻两个数的和都相等,所以最终序列奇数位置上的数都相同,偶数位置上的数也都相同。令\(m=\lfloor \frac n2\rfloor\)。则我们需要找到两个数a,b满足\((m+1)a+mb=a+b\)。发现除了n=3无解,其他n为奇数的情况都很容易找到满足要求的ab,\(a=-m,b=m+1\)即可。

时间复杂度\(O(n)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; int t,n; int main()
{
fileio(); cin>>t;
rep(tn,t)
{
cin>>n;
if(n%2==0)
{
puts("YES");
rep(i,n/2) cout<<1<<' '<<-1<<' ';
cout<<endl;
}
else
{
if(n==3) puts("NO");
else
{
puts("YES");
int nn=n/2,a=-(nn-1),b=nn;
rep(i,n)
{
if(i%2==0) cout<<a<<' ';
else cout<<b<<' ';
}
cout<<endl;
}
}
} termin();
}

C. Least Prefix Sum

令最终的前缀和数组为\(b_1\cdots b_n\)。发现\(b_m\)前面的数和后面的数是完全独立的(前面的\(a_i\)是否取反不影响后面的\(b_i\)与\(b_m\)的大小关系),可以分开处理。

以\(b_1\cdots b_{m-1}\)为例。首先如果\(a_m>0\)肯定是不行的,会导致\(b_m>b_{m-1}\),需要取反。我们可以用这种思路从\(m-1\)到0枚举,令当前枚举到i。同时维护一个数val表示\(b_m=b_i+val\)。枚举到i时我们先偷个懒,\(a_{i+1}\)先不取反,\(val+=a_{i+1}\)。如果此时\(val>0\)就有问题了,我们应该在\(a_{i+1}\cdots a_m\)中选一个没取过反的最大的正数去取反,这样是最优的。不断选没取过反的最大的正数取反,直到\(val\le 0\)为止。没取过反的正数集合可以用multiset维护。

\(b_{m+1}\cdots b_n\)是同理的。时间复杂度\(O(nlogn)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; LL t,n,m,a[200010]; int main()
{
fileio(); cin>>t;
rep(tn,t)
{
cin>>n>>m;--m;
rep(i,n) scanf("%lld",&a[i]);
multiset <LL> candel;
candel.insert(a[m]);
LL mo=a[m];//b[m]=当前+mo
LL ans=0;
for(int i=m-1;i>=0;--i)
{
while(mo>0)
{
LL val=*candel.rbegin();
++ans;
mo-=val+val;
candel.erase(--candel.end());
}
mo+=a[i];candel.insert(a[i]);
}
if(m+1<n)
{
candel.clear();mo=0;
//当前=b[m]+mo
for(int i=m+1;i<n;++i)
{
mo+=a[i];candel.insert(a[i]);
while(mo<0)
{
LL val=*candel.begin();
++ans;
mo-=val+val;
candel.erase(candel.begin());
}
}
}
cout<<ans<<endl;
} termin();
}

D. Boris and His Amazing Haircut

首先如果存在\(b_i>a_i\)肯定无解,先把这个判掉。

对于一个位置i,如果\(a_i=b_i\),那这个位置不需要特意来剪,只要所有剪到这个位置的刀的大小都\(\ge b_i\)就行了。否则,这个位置需要一个大小为\(b_i\)的刀特意来剪,且不能被\(<b_i\)的刀剪过。

对于每个\(v\),把所有需要大小为v的刀特意去剪的位置统一处理。令这些位置为\(p_1\cdots p_k\)。如果每个位置都单独剪,那需要k把刀。对于相邻的两个位置,\(p_i,p_{i+1}\),如果\([p_i+1,p_{i+1}-1]\)中所有的\(b_i\)都\(\le v\),那它们就可以合并,用同一把刀剪,省下了一把刀。最后判一下大小为v的刀够不够用即可。

时间复杂度\(O(nlogn)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; int t,n,m,a[200010],b[200010],x[200010];
map <int,vector <int> > needs;
map <int,int> hvs; namespace st
{
int n2=1,dat[800010];
void build(int k,int lb,int ub)
{
if(lb==ub)
{
if(lb<n) dat[k]=b[lb];else dat[k]=-1e9;
return;
}
build(k+k+1,lb,(lb+ub)/2);build(k+k+2,(lb+ub)/2+1,ub);
dat[k]=max(dat[k+k+1],dat[k+k+2]);
}
int qry(int k,int lb,int ub,int tlb,int tub)
{
if(ub<tlb||tub<lb) return -1e9;
if(tlb<=lb&&ub<=tub) return dat[k];
return max(qry(k+k+1,lb,(lb+ub)/2,tlb,tub),qry(k+k+2,(lb+ub)/2+1,ub,tlb,tub));
}
} int main()
{
fileio(); cin>>t;
rep(tn,t)
{
scanf("%d",&n);
needs.clear();hvs.clear();
rep(i,n) scanf("%d",&a[i]);
rep(i,n) scanf("%d",&b[i]);
bool bad=false;
rep(i,n) if(a[i]!=b[i])
{
if(b[i]>a[i]) bad=true;
else needs[b[i]].pb(i);
}
scanf("%d",&m);
rep(i,m) scanf("%d",&x[i]),++hvs[x[i]];
if(bad){puts("NO");continue;}
st::n2=1;while(st::n2<n) st::n2*=2;
rep(i,st::n2*2+3) st::dat[i]=-1e9;
st::build(0,0,st::n2-1);
for(auto it:needs)
{
int tot=it.se.size();
rep(i,it.se.size()-1)
{
int l=it.se[i],r=it.se[i+1],res=st::qry(0,0,st::n2-1,l+1,r-1);
if(res<=it.fi) --tot;
}
if(hvs.find(it.fi)==hvs.end()||hvs[it.fi]<tot)
{
bad=true;
break;
}
}
puts(bad ? "NO":"YES");
} termin();
}

E. Anya's Simultaneous Exhibition

对于两个人(a,b),如果a能赢b,我们就连一条\(a\to b\)的有向边。连出所有这样的边我们就获得了一个竞赛图。但是我们不知道这个图长什么样,只能询问一个点到一个点集的出度大小。

众所周知竞赛图一定存在哈密顿路径,所以一定有至少一个点可以到达其它所有的点,而这题中能成为candidate master(CM)的点就是这个点以及与它在同一个强连通分量内的点。

我们先用n次询问问出每个点(在整个图中)的出度。把这些点按出度从大到小排序,观察发现出度最大的点一定是CM,如果有多个出度最大的点则它们全都是。证明:假设有一个点y是CM,而出度最大的点x不是(\(out_y\ge out_x\))。那么x和y直接相连的那条边肯定是\(y\to x\)。对于x能打赢的所有点,y都必须打赢那个点,不然y就会被x间接打败,这样x就也是CM了。但y不可能打败x能打败的每个点,因为出度不够了,证毕。

现在我们要找出与出度最大的点x在同一个SCC内的所有点。我们先把整个竞赛图强连通分量分解,把每个分量看成一整个节点并拓扑排序。对于拓扑序中任意两个分量\(s_i,s_j\),显然\(s_i\)中的任意一个点都到\(s_j\)中的任意一个点有边。假设一共有k个连通分量,令x为\(s_i\)中的一个点,y为\(s_j\)中的一个点(i<j),发现x到\(s_{i+1}\cdots s_k\)中的任意点都有边;而y只可能到\(s_{j}\cdots s_k\)中的点有边,且不能到自己有边。所以x的出度一定大于y。因此,拓扑序中最靠前的那个连通块,也就是能成为CM的连通块,是由出度最大的一些点组成的。

考虑用一种类似"归纳"的方法求出这个连通块内的所有点。把所有点按照出度从大到小排序后,假设现在我们已经确定了序列的前i个点是CM。如果第\(i+1\cdots n\)个点到前i个点都没有边,那最后的答案就是前i个点。否则我们找出后面的点中第一个到\(1\cdots i\)有边的点,令其为第j个点,则它也是CM,因此第\(1\cdots j\)个点都是CM(因为CM是这个序列的一个前缀)。用这种方法不断拓展CM的边界,直到不能拓展即可。这一步最多用n-1次询问。

所以总询问数不会超过2n。

我一开始想的是能不能逐步加入每个节点,同时维护哈密顿路径,但是需要维护的信息太多了没法做

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; int n,ans[260],mark[260];
vector <pii> v; int main()
{
fileio(); cin>>n;
repn(i,n)
{
cout<<"? "<<i<<' ';
repn(j,n) if(j!=i) cout<<1;else cout<<0;
cout<<endl;
cout.flush();
int val;cin>>val;
v.pb(mpr(val,i));
}
sort(v.begin(),v.end());reverse(v.begin(),v.end());
int cur=1;
repn(i,v.size()-1)
{
cout<<"? "<<v[i].se<<' ';
memset(mark,0,sizeof(mark));
rep(j,cur) mark[v[j].se]=1;
repn(j,n) cout<<mark[j];cout<<endl;
cout.flush();
int val;cin>>val;
if(val) cur=i+1;
}
rep(i,cur) ans[v[i].se]=1;
cout<<"! ";repn(i,n) cout<<ans[i];
cout<<endl;
cout.flush(); termin();
}

F. Xorcerer's Stones

发现一旦我们对某一个点x操作过一次,再对它子树内的点操作就没有意义了。因为我们已经把x子树内所有点的权值都变成了一样的,子树怎么操作也玩不出什么花样来。唯一的问题是当x的子树大小为奇数时,无法再通过一次操作把子树中所有点的权值都变成0。但是发现对子树进行一些操作之后同样无法做到这一点。

所以我们从下往上操作。令\(dp_{i,j}\)表示对i的子树内部进行一些操作后,能不能使得子树权值异或和为j。转移的时候最所有儿子做背包即可。背包做完之后,再决定当前点要不要操作:如果此时异或和已经为0,一次操作即可把所有节点权值全变为0;如果此时异或和不为0,一次可以把所有节点权值变成一样的,两次可以全变为0。dp完了之后再倒着来一遍,构造一下方案即可。每个节点最多操作两次,所以总操作数不超过2n。

时间复杂度\(O(32^2n)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; int n,a[200010],dp[200010][40],sz[200010],dp2[200010][40],fr[200010][40];
vector <int> g[200010],ans; void dfs(int pos)
{
sz[pos]=1;
rep(i,g[pos].size()) dfs(g[pos][i]),sz[pos]+=sz[g[pos][i]];
rep(i,g[pos].size()+3) rep(j,35) dp2[i][j]=0;
dp2[0][a[pos]]=1;
rep(i,g[pos].size()) rep(j,32) if(dp2[i][j])
rep(k,32) if(dp[g[pos][i]][k]) dp2[i+1][j^k]=1;
rep(i,32) dp[pos][i]=dp2[g[pos].size()][i];
if(sz[pos]%2==0) dp[pos][0]=1;
} void dfs2(int pos,int to)
{
rep(i,g[pos].size()+3) rep(j,35) dp2[i][j]=0;
dp2[0][a[pos]]=1;
rep(i,g[pos].size()) rep(j,32) if(dp2[i][j])
rep(k,32) if(dp[g[pos][i]][k]) dp2[i+1][j^k]=1,fr[i+1][j^k]=j;
if(to==0&&dp2[g[pos].size()][0]==0)
{
repn(i,31) if(dp2[g[pos].size()][i])
{
to=i;
ans.pb(pos);ans.pb(pos);
break;
}
}
else if(to==0) ans.pb(pos);
vector <int> nxts;
int cur=to;
for(int i=g[pos].size();i>0;--i)
{
int lstj=fr[i][cur],xx=lstj^cur;
nxts.pb(xx);
cur=lstj;
}
reverse(nxts.begin(),nxts.end());
rep(i,g[pos].size()) dfs2(g[pos][i],nxts[i]);
} int main()
{
fileio(); cin>>n;
repn(i,n) scanf("%d",&a[i]);
int x;
for(int i=2;i<=n;++i)
{
scanf("%d",&x);
g[x].pb(i);
}
dfs(1);
if(dp[1][0]==0) puts("-1");
else
{
dfs2(1,0);
cout<<ans.size()<<endl;
for(int i=(int)(ans.size())-1;i>=0;--i) printf("%d ",ans[i]);
puts("");
} termin();
}

Codeforces Hello 2023 CF 1779 A~F 题解的更多相关文章

  1. Educational Codeforces Round 65 (Rated for Div. 2)题解

    Educational Codeforces Round 65 (Rated for Div. 2)题解 题目链接 A. Telephone Number 水题,代码如下: Code #include ...

  2. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  3. Educational Codeforces Round 64 (Rated for Div. 2)题解

    Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...

  4. cf 442 div2 F. Ann and Books(莫队算法)

    cf 442 div2 F. Ann and Books(莫队算法) 题意: \(给出n和k,和a_i,sum_i表示前i个数的和,有q个查询[l,r]\) 每次查询区间\([l,r]内有多少对(i, ...

  5. CF Round #580(div2)题解报告

    CF Round #580(div2)题解报告 T1 T2 水题,不管 T3 构造题,证明大约感性理解一下 我们想既然存在解 \(|a[n + i] - a[i]| = 1\) 这是必须要满足的 既然 ...

  6. Codeforces Round #612 (Div. 2) 前四题题解

    这场比赛的出题人挺有意思,全部magic成了青色. 还有题目中的图片特别有趣. 晚上没打,开virtual contest打的,就会前三道,我太菜了. 最后看着题解补了第四道. 比赛传送门 A. An ...

  7. AtCoder Beginner Contest 238 A - F 题解

    AtCoder Beginner Contest 238 \(A - F\) 题解 A - Exponential or Quadratic 题意 判断 \(2^n > n^2\)是否成立? S ...

  8. Educational Codeforces Round 61 (Rated for Div. 2) D,F题解

    D. Stressful Training 题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有n台电脑,每台电脑都有初始电量ai,也有一个 ...

  9. [题解] Codeforces Global Round 22 1738 A B C D E F 题解

    很久没rated打过cf的比赛了,这次打得还行,至少进前100了 点我看题 A. Glory Addicts 把类型0的数放进数组a里,类型1的数放进数组b里.如果\(|a|=|b|\),你可以把所有 ...

  10. CF 1132A,1132B,1132C,1132D,1132E,1132F(Round 61 A,B,C,D,E,F)题解

    A.Regular bracket sequence A string is called bracket sequence if it does not contain any characters ...

随机推荐

  1. Linux-->磁盘分区,挂载

    Linux分区 原理介绍 Linux无论有几个分区,分给哪一个目录使用,他归根结底都只有一个根目录,一个独立且唯一的文件结构,Linux中每个分区都是用来组成整个文件系统的一部分. Linux采用了一 ...

  2. 如何使用IDEA自动生成类图

    然后再类里边按 Ctrl+Alt+U 然后就会生成类图,这个样子 然后怎样把生成的类图搞出来.当然是使用截图软件啦.微信上的截图软件和qq上的截图软件好像都不在阔以,你一点击截图按钮.生成的类图就会消 ...

  3. Redis 常见问题-缓存穿透

    问题描述: * 针对 DB 中不存在的数据源,每次请求缓存和数据库都不存在 造成后果: * 应用服务器压力变大 * Redis 命中率大幅度降低 * `数据库压力巨增甚至 down 掉`* 该现象对于 ...

  4. .NET6打包部署到Windows Service

    1.安装Nuget包 安装以下nuget包支持windows service <PackageReference Include="Microsoft.AspNetCore.Hosti ...

  5. 研发效能|DevOps 已死平台工程永存带来的焦虑

    最近某位大神在推特上发了一个帖子,结果引来了国内众多卖课机构.培训机构的狂欢,开始贩卖焦虑,其实「平台工程」也不是什么特别高深莫测的东西.闲得无聊,把这位大神的几个帖子薅了下来,你看过之后就会觉得没啥 ...

  6. 京东云开发者|IoT运维 - 如何部署一套高可用K8S集群

    环境 准备工作 配置ansible(deploy 主机执行) # ssh-keygen # for i in 192.168.3.{21..28}; do ssh-copy-id -i ~/.ssh/ ...

  7. Codeforces Round #805 (Div. 3)E.Split Into Two Sets

    题目链接:https://codeforces.ml/contest/1702/problem/E 题目大意: 每张牌上面有两个数字,现在有n张牌(n为偶数),问能否将这n张牌分成两堆,使得每堆牌中的 ...

  8. VMware 虚拟机打开电源失败

    vmware上虚拟机关机导出ovf失败后,再次启动虚拟机,突然无法打开虚拟机,并伴随如下报错: 模块"disk"打开电源失败,无法打开磁盘/***/.../***.vmdk 解决方 ...

  9. yum的$releaser与$basearch

    最近配置centos 的yum 源时,想要配置一个通配的yum源,注意到发行的网络yum源的url地址中通常有两个变量 https://vault.centos.org/$releaser/cloud ...

  10. CPU cache知识 —— ARM架构cache结构和细节

    cache如何寻址 处理器访问cache时,cache电路会将CPU地址进行解码,分成3个部分,分别是: offset: 用于某个cache line -- 字抽取: index: 用于匹配某个cac ...