没有多少人用莫队做吗?

蒟蒻水一波莫队

这是一道树上莫队好题。

时间复杂度(\(n\sqrt{n}logn\))

蒟蒻过菜,不会去掉logn的做法qaq

思路很简单:

1.dfs跑一下树上点的dfs序。

2.将树上点按dfs序进行\(\sqrt{n}\) 分块。

3.对每个点按左端点的块序号和右端点的大小排序。

inline int cmp(Node aa,Node bb)
{
return aa.ls==bb.ls?aa.r<bb.r:aa.ls<bb.ls;
}

4.开始莫队,用num[x]数组统计出现x次的颜色的序号和。转移时将原先的减去,再加上现在的。

inline void add(int x)
{
int xx=coll[x];
if(num[xx])
add(num[xx],-xx,1);
num[xx]++;
add(num[xx],xx,1);
}
inline void del(int x)
{
int xx=coll[x];
add(num[xx],-xx,1);
num[xx]--;
if(num[xx])
add(num[xx],xx,1);
}

5.将num用线段树维护最大值。

6.查找num[x]中使num[x]!=0的x最大值,并num[x]为答案。(用线段树维护)

p.s.程序理论上时间复杂度爆了,但是经过我在考场上拍的时候没有多少数据可以卡掉,并且可以卡掉这个程序的数据第二次试的时候就不会爆,所以这个程序只要评测机高兴,就不会挂。

上代码(预警,代码中含有大量无用数组)

码长:3000B

当当当当

#pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
inline ll read()
{
ll f=0,x=1;char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')x=-1;ch=getchar();
}
while(ch>='0'&&ch<='9')f=(f<<1)+(f<<3)+ch-'0',ch=getchar();
return f*x;
}
ll n,col[100009],siz,cnt=0,head[100009],dfn[100009],
l[100009],r[100009],num[100009],ans=0,maxx=0,anss[100009],
coll[100009];
struct edge
{
ll to,nxt;
}e[200009];
struct Node
{
ll l,r,id,bh,col,ls,rs;
}a[100009];
struct segtree
{
ll l,r,w;
}tree[400009];
inline void adde(int a,int b)
{
cnt++;
e[cnt].nxt=head[a];
e[cnt].to=b;
head[a]=cnt;
}
inline void dfs(int x,int fa)
{
dfn[x]=++cnt;
l[cnt]=x;coll[cnt]=col[x];
a[cnt].id=x;a[cnt].l=cnt;a[cnt].col=col[x];
for(int i=head[x];~i;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;
dfs(v,x);
}
r[x]=cnt;
a[dfn[x]].r=cnt;
}
inline int cmp(Node aa,Node bb)
{
return aa.ls==bb.ls?aa.r<bb.r:aa.ls<bb.ls;
}
inline void build(int l,int r,int p)
{
tree[p].l=l;tree[p].r=r;
if(l==r)
return ;
int mid=(l+r)>>1;
build(l,mid,p*2);build(mid+1,r,p*2+1);
}
inline void add(int x,int xx,int p)
{
if(tree[p].l==tree[p].r)
{
tree[p].w+=xx;
//printf("%d %d %d\n",tree[p].l,tree[p].r,tree[p].w);
return ;
}
int mid=(tree[p].l+tree[p].r)>>1;
if(x<=mid)add(x,xx,p*2);
else add(x,xx,p*2+1);
tree[p].w=tree[p*2].w+tree[p*2+1].w;
//printf("%d %d %d %d\n",tree[p].l,tree[p].r,tree[p].w,xx);
}
inline void add(int x)
{
int xx=coll[x];
//ans[num[xx]]-=x;
if(num[xx])
add(num[xx],-xx,1);
num[xx]++;
add(num[xx],xx,1);
//printf("!!!%d %d %d\n",x,xx,a[x].id);
//ans[num[xx]]+=x
//if(num[x]==maxx)ans+=x;
}
inline void del(int x)
{
int xx=coll[x];
add(num[xx],-xx,1);
num[xx]--;
//printf("!!!%d %d %d\n",x,xx,a[x].id);
if(num[xx])
add(num[xx],xx,1);
}
inline void find(int l,int r,int p)
{
if(ans)return ;
if(l<=tree[p].l&&r>=tree[p].r){
int mid=(tree[p].l+tree[p].r)>>1;
if(tree[p].l==tree[p].r){
ans=max(ans,tree[p].w);return ;
}
if(tree[p*2+1].w)find(l,r,p*2+1);
else if(tree[p*2].w)find(l,r,p*2);
return ;
}
int mid=(tree[p].l+tree[p].r)>>1;
if(r>mid)find(l,r,p*2+1);
if(l<=mid)find(l,r,p*2);
}
int main()
{
n=read();siz=sqrt(n);
build(1,n,1);
memset(head,-1,sizeof(head));
//printf("%d\n",n);
for(int i=1;i<=n;i++){
col[i]=read();
}
for(int i=1;i<=n-1;i++){
int a=read(),b=read();
adde(a,b);adde(b,a);
}
cnt=0;
dfs(1,1);
for(int i=1;i<=n;i++)
{
a[i].ls=(a[i].l+siz-1)/siz;
}
sort(a+1,a+n+1,cmp);
int l=1,r=0;
for(int i=1;i<=n;i++)
{
ans=0;
while(r<a[i].r)add(++r);
while(r>a[i].r)del(r--);
while(l<a[i].l)del(l++);
while(l>a[i].l)add(--l);
find(1,n,1);
anss[a[i].id]=ans;
//printf("ans %d %d %d %d\n",a[i].l,a[i].r,a[i].id,ans);
}
for(int i=1;i<=n;i++)printf("%lld ",anss[i]);
return 0;
}

题解 CF600E 【Lomsat gelral】的更多相关文章

  1. CF600E Lomsat gelral 和 CF741D Dokhtar-kosh paths

    Lomsat gelral 一棵以\(1\)为根的树有\(n\)个结点,每个结点都有一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号(若有数量一样的,则求编号和). \(n \le 10^ ...

  2. 【学习笔记/题解】树上启发式合并/CF600E Lomsat gelral

    题目戳我 \(\text{Solution:}\) 树上启发式合并,是对普通暴力的一种优化. 考虑本题,最暴力的做法显然是暴力统计每一次的子树,为了避免其他子树影响,每次统计完子树都需要清空其信息. ...

  3. CF600E Lomsat gelral 【线段树合并】

    题目链接 CF600E 题解 容易想到就是线段树合并,维护每个权值区间出现的最大值以及最大值位置之和即可 对于每个节点合并一下两个子节点的信息 要注意叶子节点信息的合并和非叶节点信息的合并是不一样的 ...

  4. CF600E Lomsat gelral (启发式合并)

    You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour. Let's cal ...

  5. CF600E Lomsat gelral (dfs序+莫队)

    题面 题解 看到网上写了很多DSU和线段树合并的题解,笔者第一次做也是用的线段树合并,但在原题赛的时候却怕线段树合并调不出来,于是就用了更好想更好调的莫队. 这里笔者就说说莫队怎么做吧. 我们可以通过 ...

  6. CF600E Lomsat gelral(dsu on tree)

    dsu on tree跟冰茶祭有什么关系啊喂 dsu on tree的模板题 思想与解题过程 类似树链剖分的思路 先统计轻儿子的贡献,再统计重儿子的贡献,得出当前节点的答案后再减去轻儿子对答案的贡献 ...

  7. CF600E:Lomsat gelral(线段树合并)

    Description 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. Input 第一行一个$n$.第二行$n$个数字是$c[i]$.后面$n-1$ ...

  8. [CF600E]Lomsat gelral

    题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 线段树合并板子题,没啥难度,注意开long long 不过这题$dsu$ $on$ $tre ...

  9. dsu on tree(CF600E Lomsat gelral)

    题意 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. dsu on tree 用来解决子树问题 好像不能带修改?? 暴力做这个题,就是每次扫一遍子树统 ...

  10. cf600E. Lomsat gelral(dsu on tree)

    题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> ...

随机推荐

  1. 配置hibernate访问mysql

    在之前搭建spring mvc项目这篇的基础上继续集成,引入hibernate支持 一.添加jar包引用 修改pom.xml文件,加入: <dependency> <groupId& ...

  2. scp建立安全信任关系

    1. 在机器Client上root用户执行ssh-keygen命令,生成建立安全信任关系的证书. [root@Client root]# ssh-keygen -b 1024 -t rsa Gener ...

  3. AtCoder从小白到大神的进阶攻略

    前言 现在全球最大的编程比赛记分网站非CodeForces和AtCoder莫属了,@ezoixx130大佬已经在去年介绍过CodeForces了(传送门),那么现在我们主要谈一下AtCoder. 简介 ...

  4. elasticsearch集群扩容和容灾

    elasticsearch专栏:https://www.cnblogs.com/hello-shf/category/1550315.html 一.集群健康 Elasticsearch 的集群监控信息 ...

  5. scrapy框架来爬取壁纸网站并将图片下载到本地文件中

    首先需要确定要爬取的内容,所以第一步就应该是要确定要爬的字段: 首先去items中确定要爬的内容 class MeizhuoItem(scrapy.Item): # define the fields ...

  6. 2019-2020学年:Java自学书单(定个小目标)

    spring spring技术内幕(回顾+深入) mysql 高性能mysql innoDB (回顾+深入) redis redis实战 redis设计与实现(巩固) 算法 算法第四版 java实现 ...

  7. FTP无法登录问题-内有网盘福利

    http://dinghuqiang.blog.51cto.com/19871/701185/ 一顿操作猛如虎,还是没解决. 然后我想想,会不会是浏览器缓存问题? 换个火狐登录看看! 哇擦!看到报错了 ...

  8. setStyleSheet 设置背景图片

    设置背景颜色很简单,大部分教程都对 设置背景图像有一个小坑. 设置背景图像主要有两种情况, 第一种:图片的绝对路径 ``` this->setObjectName("mainWindo ...

  9. Python简单的登录注册代码

    #-*- coding: utf-8 -*- import hashlib # 定义数据库(声明字典) #注册登录的简单hash处理 db={} def get_md5(password): md5= ...

  10. flexible.js分析--JavaScript

    //立即执行函数 (function flexible(window, document) { // 获取的html 的根元素 var docEl = document.documentElement ...