AtCoder Grand Contest 024D: Isomorphism Freak 题解

【Atcoder】AGC024 C-F简要题解 C.贪心枚举 D.树的同构->直径,贪心构造 E.模型转化 树形DP F.序列自动机DP 阅读详情

很容易想到最终的树有两种形态
1. 一个点下面挂着若干棵完全相同的子树
2. 两棵完全相同的子树连在一起
第一部分的答案是很好算的,因为我们发现同一层的节点可以涂一样的颜色,所以我们要在原树里面找一个地方把原树“折”成两半,使得两半的深度尽可能的接近
那么这个地方显然应该是树的中心,也就是直径的中间
设直径长度为d,则若d是奇数第一问答案是d/2+1否则是d/2
考虑第二问,如果直径长度是偶数则从中间的两个点出发,每层选两者的度数最大值的较大值乘到答案里
如果直径长度是奇数,则最后树的形态可以是第一种也可以是第二种,第一种比较简单,第二种比较烦
我们考虑原树的第二层的若干棵子树,给他们编号1,2,3…m,则对于这m棵子树每一层各有一个度数最大值
再对整棵树求一个每一层的度数最大值和度数第二大值
然后我们考虑枚举第二层的每棵子树,我们要把它的第i层和“原树挖掉这棵子树”的第i层度数最大值取较大值,这个通过上面的较大值和次大值可以维护,然后原树超出当前子树深度的那部分可以提前预处理每层最大值的后缀乘积来维护
这样总复杂度O(n)O(n),但是超难写
再一看题目,什么n≤100...n≤100...
那可以有一些简单得多的O(n2)O(n2)的算法吧。。。
(感觉讲的不太清楚,看代码好了)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<int,int>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const int MOD=1e9+7;
const LL LINF=2e16;
const int INF=1e9;
const int magic=348;
const double eps=1e-10;
const double pi=3.14159265;

inline int getint()
{
    char ch;int res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

int n,tot;
vector<int> v[5000048];
int d[5000048];
int depth[5000048],fa[100048];
int dia[100048],dtot;
bool visited[5000048];

inline void dfs(int cur,int father)
{
    int i,y;fa[cur]=father;
    for (i=0;i<int(v[cur].size());i++)
    {
        y=v[cur][i];
        if (y!=father)
        {
            depth[y]=depth[cur]+1;
            dfs(y,cur);
        }
    }
}

struct node
{
    int ind,d,depth;
};
queue<node> q;
node clist[5000048];int ctot;

inline LL solve(int root)
{
    memset(depth,0,sizeof(depth));
    depth[root]=1;q.push(node{root,int(v[root].size()),1});
    int curdepth=0,maxdegree,i,j;
    LL res=1;
    while (!q.empty())
    {
        ++curdepth;ctot=0;
        while (!q.empty() && q.front().depth==curdepth) clist[++ctot]=q.front(),q.pop();
        maxdegree=0;
        for (i=1;i<=ctot;i++) maxdegree=max(maxdegree,clist[i].d),depth[clist[i].ind]=clist[i].depth;
        if (!maxdegree) maxdegree++;res*=maxdegree;
        for (i=1;i<=ctot;i++)
            for (j=0;j<int(v[clist[i].ind].size());j++)
            {
                int y=v[clist[i].ind][j];
                if (!depth[y]) q.push(node{y,int(v[y].size())-1,depth[clist[i].ind]+1});
            }
    }
    return res;
}

inline void solve1(int buttom)
{
    dtot=0;for (int cur=buttom;cur!=-1;cur=fa[cur]) dia[++dtot]=cur;
    int rt1=dia[dtot/2],rt2=dia[dtot/2+1],i;
    for (i=0;i<int(v[rt1].size());i++)
        if (v[rt1][i]==rt2) {v[rt1].erase(v[rt1].begin()+i);break;}
    for (i=0;i<int(v[rt2].size());i++)
        if (v[rt2][i]==rt1) {v[rt2].erase(v[rt2].begin()+i);break;}
    v[++tot].pb(rt1);v[tot].pb(rt2);
    v[rt1].pb(tot);v[rt2].pb(tot);
    printf("%lld\n",solve(tot));
}

vector<int> vv[100048];
int fm[5000048],sm[5000048],fmind[5000048],smind[5000048];

inline void check_max(int val,int ind,int d)
{
    if (val>=fm[d])
    {
        sm[d]=fm[d];smind[d]=fmind[d];
        fm[d]=val;fmind[d]=ind;
    }
    else if (val>sm[d])
    {
        sm[d]=val;smind[d]=ind;
    }
}

vector<int> maxdeg[100048];
int sufmax[100048];

int tt=0;
inline void bfs(int root)
{
    ++tt;
    q.push(node{root,int(v[root].size())-1,2});int i,y,curdepth=1;
    while (!q.empty())
    {
        ++curdepth;int maxdegree=0;
        while (!q.empty() && q.front().depth==curdepth)
        {
            maxdegree=max(maxdegree,q.front().d);
            depth[q.front().ind]=curdepth;
            for (i=0;i<int(v[q.front().ind].size());i++)
            {
                y=v[q.front().ind][i];
                if (!depth[y]) q.push(node{y,int(v[y].size())-1,curdepth+1});
            }
            q.pop();
        }
        check_max(maxdegree,tt,curdepth);
        maxdeg[tt].pb(maxdegree);
    }
}

inline int getmax(int d,int ind) {return fmind[d]==ind?sm[d]:fm[d];}

inline void solve2(int buttom)
{
    int i;
    dtot=0;for (int cur=buttom;cur!=-1;cur=fa[cur]) dia[++dtot]=cur;
    for (i=1;i<=n;i++) vv[i]=v[i];LL ans=LINF,cnt;
    ans=min(ans,solve(dia[dtot/2+1]));
    tot=n;for (i=1;i<=n;i++) v[i]=vv[i];
    memset(depth,0,sizeof(depth));
    memset(fm,0,sizeof(fm));memset(sm,0,sizeof(sm));
    int rt=dia[dtot/2+1];depth[rt]=1;
    for (i=0;i<int(v[rt].size());i++) bfs(v[rt][i]);
    fm[1]=int(v[rt].size())-1;fmind[1]=0;
    sufmax[n+10]=1;
    for (i=n+9;i>=1;i--)
        sufmax[i]=sufmax[i+1]*(fm[i]+(fm[i]?0:1));
    for (int cur=1;cur<=tt;cur++)
    {
        LL lnum=1;
        for (i=0;i<int(maxdeg[cur].size());i++)
        {
            int other=getmax(i+1,cur);other=max(other,maxdeg[cur][i]);
            if (!other) other++;
            lnum*=other;
        }
        int other=getmax(i+1,cur);if (!other) other++;lnum*=other;
        lnum*=sufmax[i+2];
        ans=min(ans,lnum*2);
    }
    printf("%lld\n",ans);
}

int main ()
{
    int i,x,y,maxdepth,maxind;
    n=getint();tot=n;
    for (i=1;i<=n-1;i++) x=getint(),y=getint(),v[x].pb(y),v[y].pb(x);
    depth[1]=1;dfs(1,-1);
    maxdepth=-1;for (i=1;i<=n;i++) if (depth[i]>maxdepth) maxdepth=depth[i],maxind=i;
    depth[maxind]=1;dfs(maxind,-1);
    maxdepth=-1;for (i=1;i<=n;i++) if (depth[i]>maxdepth) maxdepth=depth[i],maxind=i;
    memset(visited,false,sizeof(visited));
    if (maxdepth%2==0) printf("%d ",maxdepth/2),solve1(maxind); else printf("%d ",maxdepth/2+1),solve2(maxind);
    int cnt=0;for (i=1;i<=tot;i++) if (int(v[i].size())==1) cnt++;
    return 0;
}
Knowledge Isomorphism between Neural Networks论文笔记 Knowledge Isomorphism between Neural Networks论文笔记 Published in ArXiv 2019 原文地址 本片文章是利用knowledge isomorphism (知识同构性)去解释模型压缩和知识蒸馏。个人感觉,有值得肯定的地方,但相比于大牛文章还是差了一点火候哈。 Motivation 本文假设有两个神经网络A和B,xAx_{A}xA​和xB... 阅读详情

相关推荐

(权限题)NFLSoj #32: 辐射 题解

先吐槽一波这题实在是太难写了。。。 借鉴youyl的博客: 考虑一个辐射源对其他点的贡献,就是若干个正方形叠加在一起。 如: 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 2 2 2 1 0 0 1 2 3 2 1 0 0 1 2 2 2 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 考虑每个正方形,一个通用的思路就是差分: 0 0 0 0

IcePrincess_1968's World 736

atcoder grand contest 024

A - Fairness 给定 A,B,CA,B,CA, B, C,进行以下操作 KKK 次: 每个数都同时变为其他两个数的和 求 KKK 次操作后 A−BA−BA - B 的值,如果答案大于 1018101810^{18},输出'unfair' A,B,C≤109,K≤1018A,B,C≤109,K≤1018 A, B, C \leq 10^9, K \leq 10^{18} ...

tata_d2的博客 295

从代码层面分析STM32 标准库和HAL库的差异

相当于每个设置都是独立的函数。HAL库将一段代码通过宏定义的方式封装成了一个函数,每个端口的时钟都单独的定义了一个名称,标准库是一个独立的函数,通过参数传递的方式来设置每个端口的时钟。这两个版本的函数本质上操作的还是寄存器,不过HAL库操作的只是BSRR寄存器,而标准库端口置1的时候操作的是BSRR寄存器,端口清0的时候操作的是BRR寄存器。标准库设置端口模式的时候,是在if语句中判断之后直接设置的,而HAL端口模式设置时,却使用了switch语句去设置,说明在HAL库中,端口模式和标准库中发生了改变。

HXYDJ的博客 2万+

Python环境配置全指南:从安装到虚拟环境管理

Python环境配置是开发过程中的基础环节,直接影响项目依赖管理和运行稳定性。通过虚拟环境技术可以隔离不同项目的依赖关系,避免版本冲突。合理配置PATH环境变量和pip镜像源能显著提升开发效率。在数据科学、Web开发等不同应用场景中,Python环境配置需要针对性地安装特定工具链。本文基于Python 3.x版本,详细介绍了Windows、macOS和Linux三大平台的环境配置方法,并提供了虚拟环境管理、IDE配置等实用技巧,帮助开发者构建稳定高效的Python开发环境。

weixin_30407613的博客 378

2024.6.10丨基于DIAMOND与VFDB数据库的致病菌毒力因子高效注释指南

本文详细介绍了基于DIAMOND与VFDB数据库的致病菌毒力因子高效注释方法,涵盖工具安装、参数优化、数据库选择及实战案例解析。通过DIAMOND的快速比对和VFDB的全面毒力因子数据,显著提升微生物基因组研究效率,适用于临床检测、食品安全监测等多个场景。

weixin_33712987的博客 376

告别手动操作!用Python脚本批量处理Siemens NX零件文件(导入/导出/移除参数)

本文详细介绍了如何利用Python脚本实现Siemens NX零件文件的批量处理,包括导入、导出和移除参数等操作。通过NX Open API和Python UF接口,工业设计师可以大幅提升工作效率,告别繁琐的手动操作。文章提供了完整的实战指南,涵盖环境配置、核心功能实现以及性能优化技巧,特别适合需要进行Siemens-NXUG二次开发的工程师参考。

weixin_28222493的博客 261

Codeforces #985F: Isomorphic Strings 题解

感觉虽然是edu round的倒数第二题但还蛮简单的 我们分析那个同构的定义,可以理解为“该一样的字符要一样,该不一样的字符要不一样”,那么对于每一种字符我们想一种办法来表示他在子串中所有的出现位置(像一张有黑点的纸条),然后看看两个串能不能配对就好 把一个01串转换成一个数,我刚开始想的是高精度用2n2n2^n表示,然而复杂度是炸的,然后我发现自己蠢了,用字符串哈希就可以了 为了保险我写了...

IcePrincess_1968's World 596

线性模型:AR、MA、ARMA、ARMAX、ARX、ARARMAX、OE、BJ等

线性模型:AR、MA、ARMA、ARMAX、ARX、ARARMAX、OE、BJ等

zephyr_wang的博客 1万+

AtCoder Grand Contest 024 简要题解

链接 D: 首先观察到颜色数等于树上点的种类数。找出最长链,设长度为D,那么至少有[(D+1)/2]种。 通过把所有点都补成对称形式,这个下界也是可以达到的。 下面考虑叶子个数。 若D为偶数,显然叶子的每一层度数最大的节点(度数-1)的乘积 若D为奇数,则可以枚举最长链增长1(唯一中心点 --&gt; 两个中心点),叶子个数每种情况取min 注意代码细节,只能更专注的写才能不调试 #include...

执子之手,与子偕老 336

西电计组实验二 运算器实验

算术逻辑运算实验 一.实验目的   1.了解简单运算器的数据传输通路。   2.验证运算功能发生器的组合功能。   3.掌握算术逻辑运算加、减、与的工作原理。   4.验证实验台运算的8位加、减、与、直通功能。   5.按给定数据,完成几种指定的算术和逻辑运算。 二.实验原理   算术逻辑单元ALU的数据通路如图2-1所示。其中运算器ALU181根据74LS181的功能用VHDL硬件描述语言编辑而成,构成8位字长的ALU。参加运算的两个8位数据分别为A[7…0]和B[7…0],运算模式由S[3…0]的16种

Polaris的博客 1万+

knowhere | 第一课:项目导论与环境搭建

摘要 本课程是Knowhere项目的第一课,重点介绍项目整体架构和开发环境搭建。Knowhere定位为AI Agent的文档记忆基础设施,通过解析多格式文档并保留结构化信息(如章节层级、表格语义等),为Agent提供可导航的文档知识。项目采用Python monorepo结构,核心包括: apps/api:FastAPI服务,处理HTTP请求和流程调用 apps/worker:Celery服务,执行文档解析等耗时任务 packages/shared-python:共享基础设施层 课程明确了各层职责边界,并推

weixin_43674738的博客 153

Atcoder Grand Contest 024

A 略 B 略 C 略 D(构造分形) 题意:   给出一个由n个点的组成的树,你可以加一些点形成一个更大的树。对于新树中的两个点i和j,如果以i为根的树与以j为根的树是同构的那么i和j颜色可以相同。问最少需要多少颜色,在颜色最少的情况下,最少需要多少叶子节点。   n<=100 分析:   根据给的样例画一画,就明白是需要把树补成一个“分形”的结构,那么离分形中心距离...

weixin_30656145的博客 166

数字电视中的 Closed Caption (CC) 字幕标准协议

本文将详细介绍 DVB中的 CC 字幕标准协议,包括数据结构格式、字段定义、字段占用比特数以及字段用途。此外,本文还将举例说明如何从 TS 传输流中解析 CC 字幕信息,并组织打包到电视节目中进行显示。

以实战经验介绍行业知识 670

Atcoder agc024D

注意到若两个点为根的树深度不同一定不同构,因此答案的下界为⌈d2⌉\lceil \frac{d}{2}\rceil⌈2d​⌉(ddd为直径长度),并且容易达到下界。 若ddd为偶数,我们取原树的中心(直径的中点,在边上)为midmidmid,容易证明以midmidmid为根后,任意一层的点都需要儿子数目相同,于是根据原树可以得到每一层儿子数目的下界,容易求出最小叶子数目。 若ddd为奇数也类似,不...

mayaohua 336

Codex 100个真实案例 - 用AI自动生成API测试用例(接口测试全覆盖)

API 测试是保障后端质量的关键环节,但手写测试用例既枯燥又容易遗漏。本案例将展示如何用 Codex 从 Swagger/OpenAPI 规范文档自动生成 pytest 测试用例——包括正常流程测试、边界值测试、异常参数测试、性能压力测试,还能自动生成 Mock 数据和精美的 HTML 测试报告。全程自然语言驱动,让 API 测试覆盖率从 0 飙到 90%+!

yueyeguzhuo的专栏 271

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Atcoder Grand Contest 024 简要题解

Fairness: (A,B,C)(A,B,C)(A, B, C) 经过一次变换之后变成 (B+C,A+C,A+B)(B+C,A+C,A+B)(B + C, A + C, A + B) 再变换变成 (A+B+C+A,A+B+C+B,A+B+C+C)(A+B+C+A,A+B+C+B,A+B+C+C)(A + B + C + A, A + B + C + B, A + B + C + C) 。 如...

wxh010910 877

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【AtCoder】AtCoder Grand Contest 024

比赛链接 点击打开链接 官方题解 点击打开链接 Problem A. Fairness 由于要求计算 A−BA-BA−B ,初始序列 (A,B,C)(A,B,C)(A,B,C) 与 (A+1,B+1,C+1)(A+1,B+1,C+1)(A+1,B+1,C+1) 的结果是相同的。 令 S=A+B+C​S=A+B+C​S=A+B+C​ ,注意到两轮操作后,序列变为了 (A+S,B+S,C+S)​(A+...

cz_xuyixuan的博客 416

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

AtCoder Grand Contest 024 E - Sequence Growing Hard 动态规划

题意 给出n,k,m,问有多少个序列组(A0,A1,...,An)(A0,A1,...,An)(A_0,A_1,...,A_n)满足以下条件: 序列AiAiA_i的长度恰好为iii 所有元素均在[1,k][1,k][1,k]的范围内 Ai−1Ai−1A_{i-1}是AiAiA_i的子序列 AiAiA_i的字典序大于Ai−1Ai−1A_{i-1} 答案模mmm输出。 n,k≤300n,...

beginend 540

Little Sub and Isomorphism Sequences ZOJ - 4089

ZOJ - 4089 思路:可以反正 最长重构序列必然符合 此模式 x + { } 与 { } + x 那么 题意转化为了 找两个距离最长的相同的数。eeee 先离散化 然后 开 2e5 个set 可插入可删除的维护 每个数的 出现的位置。 然后 。 如果有set .size > = 2 则可以更新。最值 。最值可用线段树or mulitset 维护 ...

weixin_34162629的博客 153

AtCoder Grand Contest 009 D - Uninity 贪心

题意 给出一棵树,求这棵树的所有点分树中,深度最小的是多少。每次分治中心可以任意选择。 n 分析 一开始就猜会不会每次找重心就是深度最小的,然而并不是。 如果我们对点分树的每个点标号,标号为其子树深度。 显然有两个标号均为k的点,其路径上至少有一个点的标号大于k。 反过来,若我们得到了这样一组满足条件的标号,就可以得到一棵合法的点分树。 我们可以先定一个根,然后从下往上进行标号

beginend 394

AtCoder Grand Contest 024 迟到早退记+ABC题解

比赛链接 https://agc024.contest.atcoder.jp 游记 晚上九点才想起来有这个比赛…… 随便打了打,搞完ABC就21:40了,然后睡觉。 居然还上了绿名,rating+=195?震惊! A - Fairness 题目大意 一开始有333个数A,B,CA,B,CA,B,C, 每次操作AAA变成B+CB+CB+C,以此类推,问操作KKK次后A−BA−...

Canopus 462

AtCoder Grand Contest 017做题记录

诶最后三道题+第三题的部分分收场了 感觉这场比赛没怎么动脑子 不过也是NOI前最后一场AGC了吧,估计AtCoder的rating以后没机会变了A - Biscuits题意: 有NN袋饼干,第ii袋饼干大小为AiA_i,询问有多少种方案使得选出来的饼干总数模2为p N≤50,Ai≤100N\leq 50,A_i\leq100 解答: Fi,jF_{i,j}表示前ii袋饼干,选出来总和模2

HbFS- 993

Atcoder Grand Contest 024E Sequence Growing Hard

题目在这里呀! 啊啊啊准备了一个月期末考的我终于飘回来啦~~ 真可谓在学OI的时候忘不了文化课,然后在学文化课的时候又想念编程啦qwq 那那那开始我的七月第一篇题解? (我七月想写很多很多题解的w) 题意 考虑 N +1 个数组 {A0,A1,…,AN}。 其中 Ai 的长度是 i,Ai 内的所有数字都在 1 到 K 之间。 Ai−1 是 Ai 的子序列,即 Ai 删一个数字可以...

七箫. 390

[AGC024] E - Sequence Growing Hard 树型DP

把问题看成每次向序列中添加一个[1,K][1,K][1,K]的数,假设我们要填的数是xxx,因为要保证字典序变大,那么所填的位置往后的第一个非xxx数必须&amp;lt;x&amp;lt;xxxx中的任意位置再填一个xxx都是等价的,所以等同于只能在一个&amp;lt;x&amp;lt;xxxx。 那我们把填一个数看成一个二元组(t,w)(t,w)(t,w),表示在第ttt次填了数www,假设把这个www填的位置后面的那个&amp;l...

DOFYPXY的博客 917

IOI2020集训队作业-5 (CF611G, AGC034D, AGC024F)

A - CF611G New Year and Cake 题意 有一个有nnn个整点顶点凸多边形。定义一种沿着某条对角线把这个凸多边形切成两部分的方案的代价是:两部分的面积的差的绝对值。显然我们有n⋅(n−3)2n\cdot (n-3)\over 22n⋅(n−3)​种方案。你需要求出所有方案的代价的和乘二对109+710^9+7109+7取模的结果。 n≤5×105n\le 5\times 10...

这个博客已经搬到了:zhongyuwei.github.io 788

(权限题)NFLSoj #29: 环 题解

我们枚举一个中心点,称为X 将与中心点相连的点取出来,这个点集称为S 剩下的点按照联通块分成若干个点集,设第i个联通块构成的点集为Ti 找出S中与Ti中任意一点相邻的所有点,这个点集称为Gi 如果Gi中存在两个不相邻的点,那么原图一定有解 这个解是:中心点,Gi中不相邻的两个点,以及与这两个点相邻的Ti中的两个点的最短路径上的所有点,最短路径上的点是不会有不满足题意的情况的 这样总复杂

IcePrincess_1968's World 733
上一篇: AtCoder Grand Contest 024E: Sequence Growing Hard 题解
下一篇: Codeforces #985F: Isomorphic Strings 题解
IcePrincess_1968
博客等级 码龄9年 13粉丝 182原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值