当前位置: 首页 > news >正文

[BZOJ 4129]Haruna’s Breakfast(树上带修改莫队)

Description

Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了一棵

树上,每个结点都有一样食材,Shimakaze要考验一下她。
每个食材都有一个美味度,Shimakaze会进行两种操作:
1、修改某个结点的食材的美味度。
2、对于某条链,询问这条链的美味度集合中,最小的未出现的自然数是多少。即mex值。
请你帮帮Haruna吧。

Solution

树上带修改莫队

统计答案的时候也分块查询,找到第一个没满的块开始一个一个找

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define MAXN 50005
using namespace std;
int n,m,a[MAXN],head[MAXN],cnt=0,tot1=0,tot2=0,stack[MAXN],top=0;
int block,block2,tot3=0,belong[MAXN],last[MAXN],deep[MAXN],p[MAXN][22];
int ans=0,res[MAXN],num[MAXN],vis[MAXN],sg[MAXN];
int read()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<1)+(x<<3)+c-'0';c=getchar();
    }
    return x*f;
}
struct Node1
{
    int next,to;
}Edges[MAXN*2];
void addedge(int u,int v)
{
    Edges[cnt].next=head[u];
    head[u]=cnt;
    Edges[cnt++].to=v;
}
struct Node2
{
    int u,v,tim,id;
    Node2(int u=0,int v=0,int tim=0,int id=0):u(u),v(v),tim(tim),id(id){}
    bool operator < (const Node2& x) const
    {
        if(belong[u]==belong[x.u])
        {
            if(belong[v]==belong[x.v])
            return tim<x.tim;
            else return belong[v]<belong[x.v]; 
        }
        else return belong[u]<belong[x.u];
    }
}query[MAXN];
struct Node3
{
    int pos,x,pre;
    Node3(int pos=0,int x=0,int pre=0):pos(pos),x(x),pre(pre){}
}modify[MAXN];
void dfs(int u)
{
    int now=top;
    for(int i=head[u];~i;i=Edges[i].next)
    {
        int v=Edges[i].to;
        if(v==p[u][0])continue;
        p[v][0]=u,deep[v]=deep[u]+1;
        dfs(v);
        if(top-now>=block)
        {
            ++tot3;
            while(top!=now)belong[stack[top--]]=tot3;
        }
    }
    stack[++top]=u;
}
void init()
{
    for(int i=1;(1<<i)<=n;i++)
    {
        for(int j=1;j<=n;j++)
        p[j][i]=p[p[j][i-1]][i-1];
    }
}
int lca(int a,int b)
{
    if(deep[a]>deep[b])swap(a,b);
    int f=deep[b]-deep[a];
    for(int i=0;(1<<i)<=f;i++)
    if(f&(1<<i))b=p[b][i];
    if(a!=b)
    {
        for(int i=(int)log2(n);i>=0;i--)
        if(p[a][i]!=p[b][i])a=p[a][i],b=p[b][i];
        a=p[a][0];
    }
    return a;
}
void Xor(int pos)
{
    if(a[pos]>n)return;
    int b=a[pos]/block2+1;
    if(vis[pos])
    {
        num[a[pos]]--;
        if(!num[a[pos]])sg[b]--;
    }
    else
    {
        if(!num[a[pos]])sg[b]++;
        num[a[pos]]++;
    }
    vis[pos]^=1;
}
void change(int pos,int c)
{
    if(vis[pos])
    Xor(pos),a[pos]=c,Xor(pos);
    else a[pos]=c;
}
void move(int a,int b)
{
    if(deep[a]>deep[b])swap(a,b);
    while(deep[a]!=deep[b])Xor(b),b=p[b][0];
    while(a!=b){Xor(a),Xor(b);a=p[a][0],b=p[b][0];}
}
void work()
{
    int u=1,v=1;
    for(int i=1;i<=tot1;i++)
    {
        for(int j=query[i-1].tim+1;j<=query[i].tim;j++)
        change(modify[j].pos,modify[j].x);
        for(int j=query[i-1].tim;j>query[i].tim;j--)
        change(modify[j].pos,modify[j].pre);
        if(u!=query[i].u)move(u,query[i].u),u=query[i].u;
        if(v!=query[i].v)move(v,query[i].v),v=query[i].v;
        int t=lca(u,v);
        Xor(t);
        int k=1;
        while(sg[k]==block2)k++;
        k=(k-1)*block2;
        while(num[k])k++;
        res[query[i].id]=k;
        Xor(t);
    }
}
int main()
{
    memset(head,-1,sizeof(head));
    n=read(),m=read();
    block=pow(n,2.0/3),block2=sqrt(n);
    for(int i=1;i<=n;i++)last[i]=a[i]=read();
    for(int i=1;i<n;i++)
    {
        int u=read(),v=read();
        addedge(u,v);addedge(v,u);
    }
    dfs(1),init();
    for(int i=1;i<=m;i++)
    {
        int opt=read(),x=read(),y=read();
        if(opt)++tot1,query[tot1]=Node2(x,y,tot2,tot1);
        else modify[++tot2]=Node3(x,y,last[x]),last[x]=y;
    }
    sort(query+1,query+1+tot1);
    work();
    for(int i=1;i<=tot1;i++)printf("%d\n",res[i]);
    return 0;
}

 

转载于:https://www.cnblogs.com/Zars19/p/6889131.html

相关文章:

  • FileToolkit 文件工具箱
  • 解决数据架构难点数据分布的六种策略
  • Linux系统——提高编译速度的方法
  • 视频播放插件Video.js
  • Android Studio安装配置
  • WebApi接口 - 如何在应用中调用webapi接口
  • 管理两个字
  • Linux基础2
  • python 调用 zabbixApi
  • less 转栏
  • 行列式计算的两种方法
  • Android源码解析--超好看的下拉刷新动画
  • ES6核心内容精讲--快速实践ES6(二)
  • C++——编程常见错误
  • linux -硬盘分区
  • [译]前端离线指南(上)
  • Angular 响应式表单 基础例子
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • happypack两次报错的问题
  • jquery cookie
  • PAT A1092
  • Rancher-k8s加速安装文档
  • Vue小说阅读器(仿追书神器)
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 你不可错过的前端面试题(一)
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 温故知新之javascript面向对象
  • nb
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • ​Java并发新构件之Exchanger
  • $.ajax()参数及用法
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (C++)八皇后问题
  • (Forward) Music Player: From UI Proposal to Code
  • (ros//EnvironmentVariables)ros环境变量
  • (zhuan) 一些RL的文献(及笔记)
  • (九)c52学习之旅-定时器
  • (一)Dubbo快速入门、介绍、使用
  • (译) 函数式 JS #1:简介
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)visual stdio 书签功能介绍
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .NET Core 通过 Ef Core 操作 Mysql
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NET导入Excel数据
  • .net对接阿里云CSB服务
  • .net网站发布-允许更新此预编译站点
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林
  • [Android]使用Git将项目提交到GitHub
  • [C#]OpenCvSharp使用帧差法或者三帧差法检测移动物体
  • [C#]扩展方法
  • [C++]类和对象【上篇】