首页 > 其他分享 >[COCI2022-2023#1] Berilij 题解

[COCI2022-2023#1] Berilij 题解

时间:2024-05-07 21:33:54浏览次数:26  
标签:COCI2022 rt Berilij int 题解 vl ld MAXN 顶点

Solution

P9030 [COCI2022-2023#1] Berilij

本题解转载翻译自官方题解:COCI 2022/2023 CONTEST 1

Part 1

让我们定义图形 \(G\),顶点代表飞船,边代表两艘飞船外部接触的情况。此外,让边的边权成为它所连接的圆之间的距离。

现在的任务等同于为顶点找到非负值,使得每条边所连接的两个顶点值之和等于这条边的边权,其中顶点值的平方和尽可能小。

如果顶点 \((i, j)\) 与边权为 \(w_{i,j}\) 的边相连,则顶点值的条件 \(v_i \geq 0\),\(v_j \geq 0\) 与 \(v_i + v_j = w_{i,j}\) 成立。

Part 2

在 Subtask 1 中,\(G\) 是一个奇环。由于我们可以计算出每条边的值 \(w_{i,j}\),所以我们可以唯一确定环中第二个顶点的值。

现在我们尝试将第一个顶点的值增加 \(x\)。为了满足条件,我们现在需要减少第二个顶点的值,然后增加第三个顶点的值……以此类推,直到我们绕回第一个顶点,新的条件是它的值必须是 \(a-x\)。

由于 \(x = a - x\),我们可以唯一确定 \(x\) 为 \(x = \frac{a}{2}\)。

现在我们只需检查将 \(\frac{a}{2}\) 替换为第一个顶点的值是否会导致所有其他顶点的值为非负值。

Part 3

在 Subtask 3 中,\(G\) 是一个森林,但只需对每棵树分别求解即可。

为了满足任务的条件,我们现在可以唯一确定每个顶点 \(i\) 的值为线性多项式 \(\pm x + c_i\),其中 \(c_i\) 是一个常数,其值等于从顶点 \(i\) 到根的各条边的交替边权之和。

由于每个值都必须是非负值,因此 \(x + c_i\) 的顶点为 \(x\) 设定了下限,而 \(-x + c_i\) 的顶点为 \(x\) 设定了上限。如果上限小于下限,则无解。为了确定顶点值平方和最小的 \(x\),让我们求出每个顶点的线性多项式的平方和。结果是二次多项式 \(ax^2 + bx + c\)。

注意,\(a\) 等于树的大小,因此二次多项式的最小值为 \(x =-\frac{b}{2a}\)。由于这个表达式中没有使用 \(c\),而 \(b\) 等于每个顶点的 \(-2s_ic_i\) 之和,其中 \(s_i\) 是多项式 \(\pm x + c_i\) 中 \(x\) 前面的符号,因此我们可以计算出 \(-\frac{b}{2a}\),而无需将任何数字平方。如果 \(x = -\frac{b}{2a}\) 在下限和上限之间,则 \(x\) 就是我们的解,否则我们取上限或下限中更接近 \(-\frac{b}{2a}\) 的值。

Part 4

对于完整的解决方案,让我们按照 Subtask 3 的解决方案来解决任意生成树上每个分量的任务。

我们注意到,在 Subtask 3 的解法中,从根开始偶数深度的每个顶点的多项式是 \(x + c_i\),而奇数深度的每个顶点的多项式是 \(-x + c_i\)。由于偶环连接不同深度奇偶性的顶点,它们只增加了 \((+x+c_i)+(-x+c_j ) = w_{i,j}\) 形式的条件,换句话说 \(c_i + c_j = w_{i,j}\)。奇环连接深度奇偶性相同的顶点,并增加了 \((\pm x + c_i) + (\pm x + c_j ) = w_{i,j}\) 形式的条件,换句话说,\(\pm x =\frac{1}{2} (w_{i,j} - c_i - c_j)\),与 Subtask 1 一样,\(x\) 的解只有一个。

时空分析

所述算法的时间复杂度为 \(O(n+m)\)。另外,该任务也可以通过更好的三元搜索实现来解决,复杂度为 \(O((n+m)log(C\epsilon ^{-1}))\),其中 \(C\) 为坐标的最大绝对值 \(C = 10^4\),\(\epsilon\) 为所需精度。

代码

#include<bits/stdc++.h>
using namespace std;

#define int long long
#define ld long double
#define pb push_back
#define ft first
#define sd second
#define po(x) ((x)*(x))

const int MAXN=1e5+5;
const ld eps=1e-8;

int n,m;
ld sz[MAXN];
ld ans[MAXN];
ld vl[MAXN],A,B,C;
ld b[MAXN],c[MAXN];
ld lf[MAXN],rg[MAXN];
int rot[MAXN],dep[MAXN];
bool fitr[MAXN],vis[MAXN];
vector<int> Rt;
pair<ld,ld> a[MAXN];
struct edge
{
    int u,v,nxt;
    bool ontr;
    ld w;
}E[MAXN];
int su=1,hd[MAXN];

void add(int u,int v,ld w)
{
    E[++su]={u,v,hd[u],0,w},hd[u]=su;
}

ld dis(int x,int y)
{
    return sqrt(po(a[x].ft-a[y].ft)+po(a[x].sd-a[y].sd));
}

void findtree(int x,int rt)
{
    sz[rt]++;
    rot[x]=rt;
    fitr[x]=1;
    for(int i=hd[x];i;i=E[i].nxt)
    {
        int v=E[i].v;
        ld d=E[i].w;
        if(fitr[v]) continue;
        E[i].ontr=E[i^1].ontr=1;
        dep[v]=dep[x]+1;
        vl[v]=d-vl[x];
        C+=po(vl[v]);
        if(dep[v]&1)
            rg[rt]=min(rg[rt],vl[v]),b[rt]-=2*vl[v];
        else
            lf[rt]=max(lf[rt],-vl[v]),b[rt]+=2*vl[v];
        if(rg[rt]+eps<=lf[rt])
        {
            puts("NE");
            exit(0);
        }
        findtree(v,rt);
    }
}

void pushans(int x)
{
    vis[x]=1;
    for(int i=hd[x];i;i=E[i].nxt)
    {
        int v=E[i].v;
        if(vis[v]||E[i].ontr==0) continue;
        if(dep[v]&1)
            lf[v]=rg[v]=vl[v]-rg[rot[v]];
        else
            lf[v]=vl[v]+lf[rot[v]],rg[v]=vl[v]+rg[rot[v]];
        pushans(v);
    }
}

signed main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%Lf%Lf",&a[i].ft,&a[i].sd);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%lld%lld",&x,&y);
        add(x,y,dis(x,y));
        add(y,x,dis(x,y));
    }
    for(int i=1;i<=n;i++)
    {
        if(fitr[i]) continue;
        vl[i]=0;
        rg[i]=LDBL_MAX;
        findtree(i,i);
        Rt.pb(i);
    }
    for(int i=2;i<=su;i+=2)
    {
        if(E[i].ontr) continue;
        int X=E[i].u,Y=E[i].v;
        if((dep[X]&1)==(dep[Y]&1))
        {
            ld x=(E[i].w-(vl[X]+vl[Y]))/2;
            if(dep[X]&1)
                x*=-1.0;
            int rt=rot[X];
            ld l=lf[rt],r=rg[rt]; 
            if(x+eps<=l||r+eps<=x)
                return puts("NE"),0;
            lf[rt]=rg[rt]=x;
        }
        else
        {
            if(abs(vl[X]+vl[Y]-E[i].w)>eps)
                return puts("NE"),0;
        }
    }
  
    for(int i:Rt)
    {
        A=sz[i],B=b[i],C=c[i];
        ld x=-B/(2*A);
        ld l=lf[i],r=rg[i];
        if(x+eps<=l|abs(x-l)<eps)
            rg[i]=lf[i];
        else if(r+eps<=x||abs(x-r)<eps)
            lf[i]=rg[i];
        else
            lf[i]=rg[i]=x;
        pushans(i);
    }

    printf("DA\n");
    for(int i=1;i<=n;i++) printf("%.6Lf\n",abs(lf[i]));

    return 0;
}

标签:COCI2022,rt,Berilij,int,题解,vl,ld,MAXN,顶点
From: https://www.cnblogs.com/holmes-wang/p/18178438

相关文章

  • cuda使用时Could not locate zlibwapi.dll 问题解释和解决
    第一次配置cuda环境,python环境训练模型时,可能遇到Couldnotlocatezlibwapi.dll.Pleasemakesureitisinyourlibrarypath! 原因就是window系统里没有zlibwapi.dll.,与cuda没关系,cuda只是依赖它。安装某些软件时可能会自动把这个动态库安装到系统的某个path路径下,比如......
  • ICPC2024 武汉邀请赛 题解
    2024ICPCNationalInvitationalCollegiateProgrammingContest,WuhanSiteB-CountlessMeSolution显然,只能执行\(n\)次操作是没用的条件我们只需要把和\(sum\)分给\(n\)个数,使得\(n\)个数的或和最小即可从高到低考虑每一位,假设此时枚举到第\(i\)位如果这一......
  • 【题解】爬山 蓝桥杯2024省B
    题目链接:P10429[蓝桥杯2024省B]拔河[蓝桥杯2024省B]拔河题目描述小明是学校里的一名老师,他带的班级共有\(n\)名同学,第\(i\)名同学力量值为\(a_i\)。在闲暇之余,小明决定在班级里组织一场拔河比赛。为了保证比赛的双方实力尽可能相近,需要在这\(n\)名同学中挑选......
  • XMOJ 四月月赛 T3 旅行 题解
    我们首先尝试挖掘这个分组的性质。我们发现,我们可以把在同一个组的夫妻和不在同一个组的夫妻分开来处理。这里,分开之后我们只需要让一种情况有顺序,另外一种不能有顺序。如果两个没有顺序/有顺序的序列合并,一定会出现漏算/多算。所以为了方便,我们可以把第二种情况看作有顺......
  • [题解]P1757 通天之分组背包
    P1757通天之分组背包分组背包模板题。总共\(s\)组,每组最多取一个物品,实际上就是一个物品总数为\(s\)的背包。for(inti=1;i<=s;i++){//枚举组 for(intj=1;j<=n[i];j++){//枚举每组的元素 for(intk=1;k<=m;k++){//枚举背包大小 f[i][k]=max(f[i][k],f[i-1][k]); if(......
  • P9527 [JOISC2022] 洒水器 题解
    题目传送门以下设\(\operatorname{dis}(x,y)\)表示树上\(x,y\)两点间的距离。修改时对\(u\)的周围与\(u\)距离小于等于\(d\)的点的点权乘\(w\)。暴力不行,于是考虑打标记。注意到\(0\led\le40\),一个很自然的想法是:设\(tag(x,i)\)表示将\(x\)的子树内与\(x\)......
  • 数数 题解
    writeby小超手123题意:现在有四种物品,分别有\(n_{1},n_{2},n_{3},n_{4}\)个,有多少种排列物品的方案使得任意两个相邻物品的种类不同。\(n_{1},n_{2}\le200,\\n_{3},n_{4}\le50000\)。分析:可以考虑先把物品\(A,B\)排列好,再把物品\(C,D\)插入进去。需要注意的......
  • P10385 艺术与篮球 题解
    一道用编程解决的数学题。大概思路是:intmonth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};这是普通年\(12\)个月的天数。然后还要考虑闰年,有\(2000,2004,2008,2012,2016,2020,2024\)。将这些闰年的二月二十九号手算出来能不能打篮球,最后加在结果上就行了。然后循环......
  • MySQL Connection not available问题解决方案
    在后端开发过程中,连接mysql数据库,过几个小时第一次使用会出现MySQLConnectionnotavailable报错这是因为MySql数据库存在一个连接池的回收时间,超过这个时间会导致资源无法正常释放,无法连接到MySql数据库1)在相关引用页面,进行定时刷新功能,这样尽管是同一个连接,但是相当于一个新......
  • 高一下三调|ssy的队列|hash dp|题解
    SSY的队列题目链接解析:考场上看到这个题第一眼是绝望的,毕竟数论咱是一窍不通.但是往下细看了看这个数据范围,N是很小的,就想了想模拟.然而只骗到10分.这个题绩效较高的解法是状压dp,在N<15的范围之内均可薄纱(ppllxx_9G也是成功拿到这70rank1了orz),可得70,但是一到后......