点我看题

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. 2022.3.12 提高A组总结&反思

    今天有点上头了 T1:开场秒,大水题,一眼莫队了,最后没打 T2:开场以为是费用流,后来发现费用流做不了,在做T3的时候突然发现可以状压,也没打 T3:这道题给我极大的亲切感,导致我一个上午硬钢这道题 ...

  2. Linux基础_3_文件/文件夹权限管理

    注:权限遮罩码: 控制用户创建文件和文件夹的默认安全设置,文件默认权限为666-umask的值,文件夹默认权限为777-umask的值. root默认0022,普通用户默认0002. 文件的默认权限不 ...

  3. 一天十道Java面试题----第三天(对线程安全的理解------>线程池中阻塞队列的作用)

    这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 21.对线程安全的理解 22.Thread和Runnable的区别 23.说说你对守护线程的理解 24.ThreadLoc ...

  4. 创建Vue工程常用的命令

    创建一个vue项目的步骤 1.创建一个名称为myapp的工程 vue init webpack myapp 2.进入工程目录 cd myapp 3.安装 vue-router npm install ...

  5. [WPF] 抄抄超强的苹果官网滚动文字特效实现

    1. 前言 今天 ChokCoco 大佬发布了一篇博客 超强的苹果官网滚动文字特效实现,iPhone 我是买不起的,但不妨碍我对抄特效感兴趣,正好我这周安排的工作已经完成了,于是有空练练手实现了一个 ...

  6. 浅谈消息队列 Message Queue

    消息队列:在消息传递的过程中暂时保存消息的容器,充当发送者和接受者的中间人 消息队列的基本操作 using System; using System.Messaging; namespace MQ { ...

  7. 嵌入式-C语言基础:指针

    指针就是地址,变量的值可以通过两种方式访问,一个是通过变量名,一个是通过地址访问. 从而引出一个问题,即什么是指针变量?整型(字符)变量就是存放整形(字符)的变量,指针变量就是存放指针的变量,也就是存 ...

  8. C#程序自启动

    在窗体加载事件里面加入下述代码: //设置开机自启动 RegistryKey registryKey = Registry.CurrentUser.OpenSubKey ("SOFTWARE ...

  9. C#多线程之高级篇(上)

    前言 抛开死锁不谈,只聊性能问题,尽管锁总能粗暴的满足同步需求,但一旦存在竞争关系,意味着一定会有线程被阻塞,竞争越激烈,被阻塞的线程越多,上下文切换次数越多,调度成本越大,显然在高并发的场景下会损害 ...

  10. ROSIntegration ROSIntegrationVision与虚幻引擎4(Unreal Engine 4)的配置

    ROSIntegration ROSIntegrationVision与虚幻引擎4(Unreal Engine 4)的配置 操作系统:Ubuntu 18.04 虚幻引擎:4.26.2 目录 ROSIn ...