CodeForces Lomsat gelral(DSU on tree 树上启发式合并)

博客围绕有根树主导颜色求和问题展开。给出问题,即求树中每个结点对应子树的主导颜色之和。介绍DSU on tree树上启发式合并思路,先树链剖分找重儿子,dfs各节点,平衡时间空间保留重儿子贡献,分析时间复杂度为O(nlogn),最后给出AC代码。

传送门:https://codeforces.com/problemset/problem/600/E
在这里插入图片描述

题意:

给一颗n个点的有根树,每个点有一种颜色,一颗子树中出现次数最多的颜色称为主导颜色,主导颜色可能有多个,求这棵树的每个结点的对应子树的主导颜色之和

思路:

DSU on tree 树上启发式合并,先记录一下板子
··········································································································
先树链剖分找重儿子,重儿子就是最大子树的根节点
dfs每个节点,暴力计算所有轻儿子的贡献,并合并到重儿子上去
注意,轻儿子的贡献在计算之后必须要删除,不然可能会MLE,
如果都不保留,可能会TLE,所以需要平衡一下时间和空间,我们保留重儿子的贡献即可,这也是DSU on tree的意义

时间复杂度O(nlogn),以下分析来自Yveh的[trick]dsu on tree
在这种做法中,我们先进行树链剖分。
dfs的时候,首先dfs节点x的轻儿子,暴力消去影响,再dfs节点x的下一个轻儿子,依此类推。
然后dfs节点x的重儿子,无需消去影响。
在最后,我们为了统计x,再将x轻儿子的贡献加回来。
看起来很暴力,但是实际上它的时间复杂度是O(nlogn)的,跑得飞快。
可以这么考虑:
只有dfs到轻边时,才会将轻边的子树中合并到上一级的重链,树链剖分将一棵树分割成了不超过logn条重链。
每一个节点最多向上合并logn次,单次修改复杂度O(1)。
所以整体复杂度是O(nlogn)的。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
struct Edge {
	int to,next;
} e[maxn<<1];
int n,u,v,tot=1,head[maxn],siz[maxn],son[maxn];
int col[maxn],cnt[maxn],flag,maxc;
ll ans[maxn],sum;
inline void addEdge(int u,int v) {
	e[tot].to = v;
	e[tot].next = head[u];
	head[u]=tot++;
}
//重链剖分找重儿子
void dfs(int u,int f) {
	siz[u]=1;
	for(int i=head[u]; i; i=e[i].next) {
		int v=e[i].to;
		if(v==f) continue;
		dfs(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
}
//统计某结点及其所有轻儿子的贡献
void count(int u,int f,int val) {
	cnt[col[u]] += val;//val为正负用来控制是加贡献还是删除贡献
	if(cnt[col[u]]>maxc) {
		maxc=cnt[col[u]];
		sum=col[u];
	} else if(cnt[col[u]]==maxc) { //两个颜色数量相同都是主导颜色都得算
		sum+=col[u];
	}
	//排除被标记的重儿子,统计其他儿子子树信息
	for(int i=head[u]; i; i=e[i].next) {
		int v=e[i].to;
		if(v==f || v==flag) continue;
		count(v,u,val);
	}
}
//DSU on tree 的板子
void dfs(int u,int f,bool keep) {
	//第一步:搞轻儿子及其子树 算其答案 删贡献
	for(int i=head[u]; i; i=e[i].next) {
		int v=e[i].to;
		if(v==f || v==son[u]) continue;
		dfs(v,u,false);
	}

	//第二步:搞重儿子及其子树算其答案 不删贡献
	if(son[u]) {
		dfs(son[u],u,true);
		flag=son[u];
	}

	//第三步:暴力统计u及其所有轻儿子的贡献合并到刚算出的重儿子信息里
	count(u,f,1);
	flag = 0;
	ans[u] = sum;

	//把需要删除贡献的删一删
	if(!keep) {
		count(u,f,-1);
		sum=maxc=0;
	}

}
int main() {
	cin>>n;
	for(int i=1; i<=n; i++) cin>>col[i];
	for(int i=1; i<n; i++) {
		cin>>u>>v;
		addEdge(u,v),addEdge(v,u);
	}
	dfs(1,0);
	dfs(1,0,0);
	for(int i=1; i<=n; i++) {
		cout<<ans[i]<<" ";
	}
}
基于 NSFW Model 色情图片识别鉴黄 后面更新视频检测 项目背景: 随着互联网的快速发展,网络上的信息量呈现出爆炸式的增长。然而,互联网上的内容良莠不齐,其中不乏一些不良信息,如色情、暴力等。这些信息对青少年的健康成长和社会风气产生了不良影响。为了净化网络环境,保护青少年免受不良信息的侵害,我国政府加大了对网络内容的监管力度。在此背景下,本项目应运而生,旨在实现对网络图片和视频的自动识别与过滤,助力构建清朗的网络空间。 项目简介: 本项目基于 NSFW(Not Safe For Work)Model,利用深度学习技术对色情图片进行识别与鉴黄。NSFW Model 是一种基于卷积神经网络(CNN)的图像识别模型,通过学习大量的色情图片和非色情图片,能够准确地判断一张图片是否含有色情内容。本项目在 NSFW Model 的基础上,进一步优化了模型结构,提高了识别的准确率和效率。 项目功能: 色情图片识别:用户上传图片后,系统会自动调用 NSFW Model 对图片进行识别,判断图片是否含有色情内容。如果含有色情内容,系统会给出相应的提示,并阻止图片的传播。 视频检测:针对网络视频,本项目采用帧提取技术,将视频分解为一帧帧图片,然后使用 NSFW Model 对这些图片进行识别。如果检测到含有色情内容的图片,系统会给出相应的提示,并阻止视频的传播。 实时监控:本项目可应用于网络直播、短视频平台等场景,实时监控画面内容,一旦检测到含有色情内容的画面,立即进行屏蔽处理,确保网络环境的纯洁。
### 如何在本地部署 NSFW 模型或服务 要在本地环境中成功部署 NSFW(不适宜工作场合内容)检测模型或服务,以下是详细的说明: #### 准备环境 为了确保能够顺利运行模型和服务,需要安装必要的依赖项。这些工具和库包括但不限于以下几类: - **Python 环境**: 推荐使用 Python 3.7 或更高版本。 - **Transformers 库**: 提供加载预训练模型的功能[^1]。 - **PyTorch/TensorFlow**: 支持深度学习框架的计算需求。 - **Pillow (PIL)**: 处理图像文件并将其转换为适合输入模型的形式。 具体命令如下所示: ```bash pip install transformers torch Pillow ``` #### 加载模型与测试 通过 Hugging Face 的 `transformers` 工具包可以直接访问已有的 NSFW 图片分类模型。例如,可以采用名为 `"Falconsai/nsfw_image_detection"` 的公开模型来完成此任务[^1]。 下面是一个简单的代码片段展示如何加载该模型并对单张图片执行预测操作: ```python from PIL import Image from transformers import pipeline def classify_nsfw(image_path): # 打开指定路径下的图片文件 img = Image.open(image_path) # 初始化 image-classification 流水线对象,并指明使用的特定模型名称 classifier = pipeline("image-classification", model="Falconsai/nsfw_image_detection") # 对传入的图片调用流水线方法得到其类别标签及其置信度分数列表形式的结果 result = classifier(img) return result if __name__ == "__main__": test_img_path = "<your_test_image>" output_results = classify_nsfw(test_img_path) print(output_results) ``` 注意替换 `<your_test_image>` 成实际存在的图片绝对或者相对地址字符串值之前再尝试运行以上脚本。 #### 构建 RESTful API 服务 如果希望进一步扩展功能至 Web 应用程序层面,则可考虑利用 Flask/Django 这样的轻量级 web 开发框架构建起支持 HTTP 请求交互的服务端接口。这里给出基于 FastAPI 实现的一个简单例子作为示范用途: ```python import uvicorn from fastapi import FastAPI, File, UploadFile from PIL import Image from io import BytesIO from typing import List from pydantic import BaseModel app = FastAPI() class Prediction(BaseModel): label: str score: float @app.post("/predict/", response_model=List[Prediction]) async def predict(file: UploadFile = File(...)): try: contents = await file.read() pil_image = Image.open(BytesIO(contents)) clf_pipeline = pipeline('image-classification', model='Falconsai/nsfw_image_detection') predictions = clf_pipeline(pil_image) formatted_preds = [{"label": pred['label'], "score": round(pred['score'], 4)} for pred in predictions] return formatted_preds except Exception as e: raise ValueError(f"Error processing uploaded file {e}") if __name__ == '__main__': uvicorn.run(app, host='0.0.0.0', port=8000) ``` 启动服务器之后即可向 `/predict/` 路径发送 POST 请求附带上传待分析的目标图片获取返回结果了。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值