染色

本文详细介绍了处理树形结构中特定查询问题的一种高效算法——点剖算法,并对比了传统的树剖方法,通过实例解释了如何利用点剖来优化查询效率至仅需一个log的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

给定一颗树,每个点默认白色,有两种操作。
把一个点染黑(不保证此时该点为白色)
询问一个点与所有黑点的距离和

树剖

先把原树转化为有根树。
然后询问一个点u,就是枚举每一个黑点v
然后贡献为d[u]+d[v]-2*d[lca(u,v)]
记录黑点的总个数和深度和,前两项很容易求和,最后一项呢?
我们尝试枚举u到root路径上的每一点w,设size[w]表示w是多少个黑点的祖先。
那么贡献为f[w]*size[w],其中f[i]表示i到父亲的距离。
然后明显可以用树链剖分搞了。

两个log不优美

其实这道题我们可以做到一个log。
考虑点剖:
belong[i,j]表示分治到第j层i属于分治中心的哪个子树内。
d[i,j]表示分治到第j层i到分治中心的距离。
cen[i,j]表示分治到第j层i所属的分治中心。
ans[j]表示j作为分治中心时以其为根的子树内所有黑点到其的距离和。
num[i,j]表示分治到第j层以i为根的子树内所有黑点到分治中心的距离和(i与分治中心有一条边直接相连)
cnt[j]表示j作为分治中心时以其为根的子树内黑点的个数(不考虑分治中心是否为黑点)
sum[i,j]表示分治到第j层以i为根的子树内黑点的个数(i与分治中心有一条边直接相连)
询问操作(询问x到所有黑点的距离和):
从小到大枚举层数j。
如果在第j层x是分治中心则答案加上ans[x]并退出。
否则,答案加上ans[cen[x,j]]-num[belong[x,j],j]+d[x,j]*(cnt[cen[x,j]]-sum[belong[x,j],j])。
然后,若分治中心(即cen[x,j])为黑点,再给答案加上d[x,j]。
感觉这题解就是代码即代码注释(囧
修改操作(把x染黑):
x是黑点那我们啥也不干。
从小到大枚举层数j。
如果第j层x是分治中心就退出。
否则更新一下ans、num、cnt、sum。
详见代码QAQ。

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int maxn=100000+10;
int belong[maxn][20],cen[maxn][20],size[maxn],a[maxn],dep[maxn],cnt[maxn];
int h[maxn],go[maxn*2],next[maxn*2],sum[maxn][20];
ll d[maxn][20],num[maxn][20],dis[maxn*2],ans[maxn];
bool bz[maxn];
int i,j,k,l,t,n,m,x,tot,top;
ll now;
void add(int x,int y,int z){
    go[++tot]=y;
    dis[tot]=z;
    next[tot]=h[x];
    h[x]=tot;
}
void dfs(int x,int y){
    a[++top]=x;
    int t=h[x];
    size[x]=1;
    while (t){
        if (go[t]!=y&&!bz[go[t]]){
            dfs(go[t],x);
            size[x]+=size[go[t]];
        }
        t=next[t];
    }
}
void dg(int x,int y,int z,int d){
    belong[x][d]=z;
    int t=h[x];
    while (t){
        if (go[t]!=y&&!bz[go[t]]){
            dep[go[t]]=dep[x]+dis[t];
            dg(go[t],x,z,d);
        }
        t=next[t];
    }
}
void solve(int x,int y){
    top=0;
    dfs(x,0);
    int i,j=x,k=0,t;
    while (1){
        t=h[j];
        while (t){
            if (go[t]!=k&&!bz[go[t]]&&size[go[t]]>top/2){
                k=j;
                j=go[t];
                break;
            }
            t=next[t];
        }
        if (!t) break;
    }
    dep[j]=0;
    t=h[j];
    while (t){
        if (!bz[go[t]]){
            dep[go[t]]=dep[j]+dis[t];
            dg(go[t],j,go[t],y);
        }
        t=next[t];
    }
    fo(i,1,top) d[a[i]][y]=dep[a[i]],cen[a[i]][y]=j;
    bz[j]=1;
    t=h[j];
    while (t){
        if (!bz[go[t]]) solve(go[t],y+1);
        t=next[t];
    }
}
int main(){
    freopen("color1.in","r",stdin);
    scanf("%d%d",&n,&m);
    fo(i,2,n) scanf("%d",&a[i]),a[i]++;
    fo(i,2,n) scanf("%d",&dep[i]);
    fo(i,2,n) add(i,a[i],dep[i]),add(a[i],i,dep[i]);
    solve(1,0);
    fo(i,1,n) bz[i]=0;
    while (m--){
        scanf("%d%d",&t,&x);
        x++;
        if (t==1){
            if (bz[x]) continue;
            j=0;
            bz[x]=1;
            while (cen[x][j]!=x){
                ans[cen[x][j]]+=d[x][j];
                num[belong[x][j]][j]+=d[x][j];
                cnt[cen[x][j]]++;
                sum[belong[x][j]][j]++;
                j++;
            }
        }
        else{
            now=j=0;
            while (1){
                if (cen[x][j]==x){
                    now+=ans[x];
                    break;
                }
                else{
                    now+=ans[cen[x][j]]-num[belong[x][j]][j];
                    now+=(ll)d[x][j]*(cnt[cen[x][j]]-sum[belong[x][j]][j]);
                    if (bz[cen[x][j]]) now+=d[x][j];
                }
                j++;
            }
            printf("%lld\n",now);
        }
    }
}

后续

我发现wyx的代码又短又快!
点进去是个大暴力!
我仔细思考这个问题并得到了结论——
i的父亲的编号小于i,这样随机出来的树期望高度为log n!
而这题就是采取了这种随机方法!
(出题人居然全随机数据……

在AI图像染色、生物染色以及深度学习上色技术方面,这些领域均依赖于人工智能的预测与优化能力,以实现更精准、高效的着色或染色效果。以下是对这些方向的详细说明: ### AI 图像染色 AI图像染色通常指将灰度图像(黑白图像)自动转换为彩色图像的过程。传统的图像处理方法需要人工干预,例如通过调整色彩曲线和颜色占比来手动上色,这种方法效率较低且难以保证结果的真实感[^1]。而基于深度学习的方法,如卷积神经网络(CNN)和生成对抗网络(GAN),可以实现自动化上色,并达到较高的视觉质量。 - **深度学习模型**:使用Caffe、TensorFlow、PyTorch等框架训练出的模型能够从大量数据中学习色彩分布规律,并对输入的黑白图像进行语义级别的色彩预测。 - **GAN 应用**:近年来,GAN(生成对抗网络)被广泛应用于图像上色任务中,其优势在于能够生成更具真实感的色彩效果,尤其适用于人像、建筑图等复杂场景[^2]。 ### 生物染色中的AI应用 在生物学和医学影像分析中,染色是指通过化学染料使组织切片或细胞结构显色,以便于观察。AI在此领域的应用主要体现在以下几个方面: - **染色模式识别**:深度学习可用于识别不同类型的染色模式,例如H&E染色、免疫组化染色等,从而辅助病理诊断。 - **虚拟染色(Virtual Staining)**:利用AI模拟染色过程,减少实际染色所需时间与成本。例如,通过深度学习模型预测未染色样本在特定染色下的外观[^3]。 - **染色增强与复原**:AI可以用于改善染色不均匀、褪色等问题,提升图像质量,便于后续分析。 ### 深度学习上色技术 深度学习上色技术不仅限于图像恢复,也扩展到了视频修复、医学成像、艺术创作等多个领域。其核心思想是通过训练模型理解图像内容并预测合理的颜色分布。 - **端到端训练**:现代模型采用端到端的方式训练,输入为灰度图,输出为RGB彩色图像,整个过程由神经网络自动完成。 - **多尺度特征提取**:为了提高上色准确性,许多模型引入注意力机制或多尺度特征融合策略,以更好地捕捉图像中的上下文信息。 - **用户交互式调整**:部分系统允许用户进行少量交互操作(如局部颜色提示),再由AI完成全局上色,提升可控性与灵活性。 ### 示例代码:基于PyTorch的图像上色模型简要实现 以下是一个简化版的图像上色模型定义示例,使用PyTorch框架: ```python import torch import torch.nn as nn class ColorizationNet(nn.Module): def __init__(self): super(ColorizationNet, self).__init__() # 编码器部分(简化) self.encoder = nn.Sequential( nn.Conv2d(1, 64, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2) ) # 解码器部分(简化) self.decoder = nn.Sequential( nn.ConvTranspose2d(64, 3, kernel_size=4, stride=2, padding=1), nn.Sigmoid() ) def forward(self, x): x = self.encoder(x) x = self.decoder(x) return x # 实例化模型 model = ColorizationNet() ``` 该模型仅作为演示用途,实际部署需结合大规模图像数据集进行训练,并可能引入更复杂的结构如ResNet、U-Net等以提升性能。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值