A. Flip Flop Sum

能换 \(-1,-1\) 就换,不能能换 \(1,-1\) 或 \(-1,1\) 也可以,否则只能换 \(1,1\)。

B. The Forbidden Permutation

如果原序列一开始就是好的那就结束,否则尝试打破一边的不等号即可。

C. Flexible String

暴力搜索每一个字符是否在 \(S\) 当中。时间复杂度 \(O(n2^{|\Sigma|})\)

D. Flexible String Revisit

随机给 \(01\) 串取反,问变到全 \(0\) 的期望步数。

考虑 \(f_i\) 表示当前有 \(i\) 个 \(1\) 的期望步数。不难有:

\[f_0=0,f_i=\dfrac inf_{i-1}+\dfrac{n-i}n f_{i+1}+1
\]

我们假设 \(f_n=x\),我们可以把每一个 \(f\) 写成关于 \(x\) 的一次函数,推回到 \(f_0\) 时解出 \(x\) 即可。

给一段参考代码。

void init(){
// 求 p[n]
a[n]=1,b[n]=0;
for(int i=n;i>=1;i--){
// ip[i-1]=np[i]-(n-i)p[i+1]-n
a[i-1]=(n*a[i]%MOD-(n-i)*a[i+1]%MOD+MOD)%MOD*inv(i)%MOD;
b[i-1]=((n*b[i]%MOD-(n-i)*b[i+1]%MOD+MOD)%MOD-n+MOD)*inv(i)%MOD;
}
ll x=(MOD-b[0])*inv(a[0])%MOD;
for(int i=0;i<=n;i++)
p[i]=(a[i]*x+b[i])%MOD;
}

E. The Tree Has Fallen!

  • 给一棵点权树,每次询问查询以 \(r\) 为根时 \(u\) 的子树当中可选若干点权异或最大。
  • \(n,q\leq2\times 10^5\)。

首先这个问题显然时线性基,我们考虑对每个结点维护一个线性基存入他的子树点权。由于根可能被改变,所以需要换根。

更具体的,当我们把根从 \(u\) 换到 \(v\) 的时候,那么 \(v\) 的线性基就会变成全部元素的线性基,但是 \(u\) 的线性基会变成所有节点去除 \(v\) 节点的线性基的合并。但是线性基没有可减性,所以我们需要维护一个节点的相邻节点的前缀线性基,后缀线性基才可以完成转移。

代码写起来很丑,而且常熟巨大,当乐子看就好了。听说有 dfs 序的简单一点的代码,但是懒得打。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define ll long long
#define MP make_pair
const int MAXN=2e5+5;
int _;
struct Xxj{
int a[32];
}xxj[MAXN];
int ask(Xxj x){
ll res=0;
for(int i=31;i>=0;i--)
if((res&(1<<i))==0)
res^=x.a[i];
return res;
}
void insert(Xxj &x,int k){
for(int i=31;i>=0;i--)
if(!x.a[i]&&(k&(1<<i))){
x.a[i]=k;
return;
}else if(k&(1<<i))k^=x.a[i];
}
Xxj merge(Xxj x,Xxj y){
Xxj res=x;
for(int i=31;i>=0;i--)
if(y.a[i])
insert(res,y.a[i]);
return res;
}
void Clear(Xxj &x){
for(int i=31;i>=0;i--) x.a[i]=0;
}
vector<int> ve[MAXN];
vector<pair<int,int> > qe[MAXN];
int ans[MAXN];
int n,q,a[MAXN];
void dfs(int u,int fa){
insert(xxj[u],a[u]);
for(int v:ve[u]) if(v!=fa){
dfs(v,u);
xxj[u]=merge(xxj[u],xxj[v]);
}
}
void dfs_root(int u,int fa){
for(auto i:qe[u])
ans[i.second]=ask(xxj[i.first]);
int sz=ve[u].size();
vector<Xxj> pl(sz+1),pr(sz+1);
pl[0]=xxj[ve[u][0]];
pr[sz-1]=xxj[ve[u][sz-1]];Clear(pr[sz]);
for(int i=1;i<sz;i++)
pl[i]=merge(pl[i-1],xxj[ve[u][i]]);
for(int i=sz-2;i>=0;i--)
pr[i]=merge(pr[i+1],xxj[ve[u][i]]);
Xxj rt=xxj[u],copy;
for(int i=0;i<sz;i++)if(ve[u][i]!=fa){
if(!i) xxj[u]=pr[i+1];
else xxj[u]=merge(pl[i-1],pr[i+1]);
insert(xxj[u],a[u]);
copy=xxj[ve[u][i]],xxj[ve[u][i]]=rt;
dfs_root(ve[u][i],u);
xxj[ve[u][i]]=copy;
}
xxj[u]=rt;
return;
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++) ve[i].clear(),qe[i].clear(),Clear(xxj[i]);
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
ve[u].push_back(v);
ve[v].push_back(u);
}
cin>>q;
for(int i=1;i<=q;i++){
int r,u;cin>>r>>u;
qe[r].push_back(MP(u,i));
}
dfs(1,0);
dfs_root(1,0);
for(int i=1;i<=q;i++)
cout<<ans[i]<<endl;
return;
}
int main(){
cin>>_;
while(_--)
solve();
}

F. Maximizing Root

  • 给一颗点权树(\(1\) 为根),每次可以选择一个未选择过的节点 \(u\) 然后把他的所有儿子点权乘上这颗子树所有节点点权的 \(\gcd\)。
  • 最多 \(k\) 次操作,最大化 \(1\) 的点权。
  • \(n\leq10^5,a_i\leq10^3\)。

显然操作肯定时自下而上的,也就是不会选择了一个祖先又选择了一个儿子。对于一次操作来说,变化的是一个子树的 \(\gcd\) 变成了它本身的平方。

考虑树形 dp。\(f_{i,j}\) 表示对 \(i\) 的子树,不操作根节点要所有权值都是 \(j\) 的倍数的最小操作数,容易得到转移:

\[f_{i,j}=\sum_{v\in son_i} \min(f_{v,j},(\min_{j|k^2} f_{v,k})+1)
\]

这个转移是 \(d(V)^2\) 的。总的时间复杂度时 \(O(n d^2(V))\),得以通过。

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
const int MAXN=1e5+5;
const int MR=1005;
int f[MAXN][1005];// f[i][j] 表示 i 子树公约数 j 倍数最小操作数
vector<int> ve[MAXN],d[MR];
int tmp[1005],a[MAXN];
int n,k;
int gcd(int x,int y){
return (x%y==0)?y:gcd(y,x%y);
}
void dfs(int u,int fa){
for(int i:d[a[u]]) f[u][i]=0;
for(int v:ve[u])if(v!=fa){
dfs(v,u);
for(int p:d[a[v]]) if(f[v][p]!=1e9){
int g=gcd(a[u],p);
tmp[g]=min(tmp[g],f[v][p]);
g=gcd(a[u],p*p);
tmp[g]=min(tmp[g],f[v][p]+1);
}
for(int i:d[a[u]])
for(int j:d[i]) tmp[j]=min(tmp[j],tmp[i]);
for(int i:d[a[u]])
f[u][i]=min(f[u][i]+tmp[i],(int)1e9),tmp[i]=1e9;
}
return;
}
void solve(){
cin>>n>>k;
for(int i=1;i<=n;i++) ve[i].clear();
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
ve[u].push_back(v);
ve[v].push_back(u);
}
if(k==0){
cout<<a[1]<<endl;
return;
}
dfs(1,0);
int ans=0;
for(int i:d[a[1]])
if(f[1][i]<k) ans=max(ans,a[1]*i);
cout<<ans<<endl;
return;
}
int main(){
for(int i=1;i<MR;i++){
tmp[i]=1e9;
for(int j=i;j<MR;j+=i)
d[j].push_back(i);
}
int _;cin>>_;
while(_--) solve();
}

Codeforces Round #848 (Div. 2) A~F 题解的更多相关文章

  1. Codeforces Round #648 (Div. 2) A~F题解

    开始补cf了,还是记录一下,加深思路,打的应该都是div2.题面不截图了,直接说题意,思路,代码. A 题意:给一个01矩阵,两个人轮流填格子,仅当第i行,第j列全为0时才能填,不能填的人输,问谁赢? ...

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

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

  3. Codeforces Round #198 (Div. 2)A,B题解

    Codeforces Round #198 (Div. 2) 昨天看到奋斗群的群赛,好奇的去做了一下, 大概花了3个小时Ak,我大概可以退役了吧 那下面来稍微总结一下 A. The Wall Iahu ...

  4. Codeforces Round #573 (Div. 1) 差F

    Codeforces Round #573 (Div. 1) E 题意:二维平面上有 n 个点,你可以放至多 m 条直线使得 (0,0) 与每个点的连线至少与一条直线相交.求原点与所有直线的距离最小值 ...

  5. Codeforces Round #672 (Div. 2) A - C1题解

    [Codeforces Round #672 (Div. 2) A - C1 ] 题目链接# A. Cubes Sorting 思路: " If Wheatley needs more th ...

  6. Codeforces Round #532 (Div. 2):F. Ivan and Burgers(贪心+异或基)

    F. Ivan and Burgers 题目链接:https://codeforces.com/contest/1100/problem/F 题意: 给出n个数,然后有多个询问,每次回答询问所给出的区 ...

  7. Codeforces Round #611 (Div. 3) A-F简要题解

    contest链接:https://codeforces.com/contest/1283 A. Minutes Before the New Year 题意:给一个当前时间,输出离第二天差多少分钟 ...

  8. Codeforces Round #541 (Div. 2) (A~F)

    目录 Codeforces 1131 A.Sea Battle B.Draw! C.Birthday D.Gourmet choice(拓扑排序) E.String Multiplication(思路 ...

  9. Codeforces Round #198 (Div. 2)C,D题解

    接着是C,D的题解 C. Tourist Problem Iahub is a big fan of tourists. He wants to become a tourist himself, s ...

  10. Codeforces Round #615 (Div. 3) A-F简要题解

    contest链接:https://codeforces.com/contest/1294 A. 给出a.b.c三个数,从n中分配给a.b.c,问能否使得a = b = c.计算a,b,c三个数的差值 ...

随机推荐

  1. GIT专业术语教程-转载

    目录 一.版本控制概要 1.1.什么是版本控制 1.2.常用术语 1.3.常见的版本控制器 1.4.版本控制分类 1.4.1.本地版本控制 1.4.2.集中版本控制 1.4.3.分布式版本控制 1.5 ...

  2. 18.3 NPCAP自定义数据包过滤

    NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库.它是WinPcap库的一个分支,由Nmap开发团队开发,并在Nmap软件中使用.与WinPcap一样,NPCAP库提供了一些 ...

  3. LyScript 实现绕过反调试保护

    LyScript插件中内置的方法可实现各类反调试以及屏蔽特定API函数的功能,这类功能在应对病毒等恶意程序时非常有效,例如当程序调用特定API函数时我们可以将其拦截,从而实现保护系统在调试时不被破坏的 ...

  4. 小知识:开启NTP服务并设置为开机启动

    我的一套测试环境发现时间慢了10分钟,影响我做各类测试. 首先就想到NTP服务,发现已安装NTP安装包,也有默认的NTP配置文件,只是没有启用. 用到的相关命令参考如下: [root@bogon ~] ...

  5. FDConnection的事务测试讲解。。

    总之用事务的宗旨是: 1.不用嵌套事务EnableNested设置为False 2.事务一定要回滚,避免发生异常的情况下,没有回滚 造成,不可估量的错误. try frmClientDm.MyMain ...

  6. Pandas数据合并

    目录 1) 在单个键上进行合并操作 2) 在多个键上进行合并操作 使用how参数合并 1) left join 2) right join 3) outer join(并集) 4) inner joi ...

  7. mysql 外键索引入门介绍,为什么工作中很少有人使用?

    背景 以前工作学习中,一直被告诫不要使用外键,所以也没有仔细整理过. 这里记录一下笔记. 外键 是什么? MySQL 的外键(Foreign Key)是一种关系型数据库中用于建立表与表之间关联关系的重 ...

  8. STM32F401的外部中断EXTI

    stm32f401 EXTI EXTI就是External interrupt/event controller, 外部事件和中断控制器, 包含21条边沿检测线. 每条线可以独立设置触发事件(上升沿, ...

  9. python中矩阵切片维数微秒变化

    1 前言 使用切片访问矩阵的部分数据(特别是一行或一列数据)时,通常会出现切片维数怎么在瞎变化,以致于不得不用reshape()强制改变维数.在深度学习中,网络对矩阵维数的要求是非常严格的,往往就是这 ...

  10. Vue+SpringBoot+ElementUI实战学生管理系统-6.院系管理模块

    1.章节介绍 前一篇介绍了用户管理模块,这一篇编写院系管理模块,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.实现效果 院系列表 修改院系 4.模块 ...