[Codechef - ADITREE] Adi and the Tree

Description

树上每个节点有一个灯泡,开始所有灯泡都是熄灭的。每次操作给定两个数 \(a,b\) ,将 \(a,b\) 这两个节点的灯的状态改变。定义某个状态的权值为,将树上所有亮点两两配对,每个对的权值的总和最小值。其中一个配对的权值定义为这两个点之间的距离。求出每次操作后的权值。

Solution

很容易发现如果我们将每个亮点到树根的路径染色,那么染色次数为奇数的路径就会被统计入答案。

所以只需要维护布尔值就可以,这样每次操作就转化为对点到根的路径异或,询问就是整棵树的权和。树链剖分一下就可以。

#include <bits/stdc++.h>
using namespace std; const int N = 1000005; namespace seg
{
int val[N],tag[N];
void pushup(int p)
{
val[p]=val[p*2]+val[p*2+1];
}
void pushdown(int p,int l,int r)
{
if(tag[p])
{
tag[p*2]^=1;
tag[p*2+1]^=1;
val[p*2]=((l+r)/2-l+1)-val[p*2];
val[p*2+1]=(r-(l+r)/2)-val[p*2+1];
tag[p]^=1;
}
}
void modify(int p,int l,int r,int ql,int qr)
{
if(l>qr || r<ql)
return ;
if(l>=ql && r<=qr)
{
val[p]=(r-l+1)-val[p];
tag[p]^=1;
}
else
{
pushdown(p,l,r);
modify(p*2,l,(l+r)/2,ql,qr);
modify(p*2+1,(l+r)/2+1,r,ql,qr);
pushup(p);
}
}
int query()
{
return val[1];
}
} // seg namespace tree
{
vector <int> g[N];
int n,top[N],wson[N],siz[N],dep[N],vis[N],tid[N],did[N],fa[N],cnt=0;
void link(int p,int q)
{
g[p].push_back(q);
g[q].push_back(p);
}
void dfs1(int p)
{
vis[p]=siz[p]=1;
for(int i=0; i<g[p].size(); i++)
{
if(vis[g[p][i]]==0)
{
dep[g[p][i]]=dep[p]+1;
fa[g[p][i]]=p;
dfs1(g[p][i]);
siz[p]+=siz[g[p][i]];
if(wson[p]==0 || siz[g[p][i]]>siz[wson[p]])
wson[p]=g[p][i];
}
}
}
void dfs2(int p)
{
vis[p]=1;
did[p]=++cnt;
tid[cnt]=p;
if(wson[p])
{
top[wson[p]]=top[p];
dfs2(wson[p]);
}
for(int i=0; i<g[p].size(); i++)
{
if(vis[g[p][i]]==0)
{
top[g[p][i]]=g[p][i];
dfs2(g[p][i]);
}
}
}
void presolve()
{
dep[1]=1;
dfs1(1);
memset(vis,0,sizeof vis);
top[1]=1;
dfs2(1);
} void link_modify(int p,int q)
{
while(top[p]-top[q])
{
if(dep[top[p]]>dep[top[q]])
swap(p,q);
seg::modify(1,1,n,did[top[q]],did[q]);
q=fa[top[q]];
}
if(dep[p]>dep[q])
swap(p,q);
seg::modify(1,1,n,did[p],did[q]);
}
} int n,m,t1,t2,t3; int main()
{
scanf("%d",&n);
for(int i=1; i<n; i++)
{
scanf("%d%d",&t1,&t2);
tree::link(t1,t2);
}
tree::n=n;
tree::presolve();
scanf("%d",&m);
for(int i=1; i<=m; i++)
{
scanf("%d%d",&t1,&t2);
tree::link_modify(1,t1);
tree::link_modify(1,t2);
printf("%d\n",seg::query());
}
}

[Codechef - ADITREE] Adi and the Tree - 树链剖分,线段树的更多相关文章

  1. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  2. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  3. POJ3237 Tree 树链剖分 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...

  4. 【CF725G】Messages on a Tree 树链剖分+线段树

    [CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...

  5. Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  6. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

  7. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  8. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  9. B20J_3231_[SDOI2014]旅行_树链剖分+线段树

    B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...

  10. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

随机推荐

  1. 初始socket编程

    服务端语法 import socket # 导入套接字模块# 生成一个socket对象进行网络编程操作server = socket.socket(family=socket.AF_INET, typ ...

  2. Linux中“没有可用的软件包XX,但是它被其他软件包引用”的解决方法

    踩坑经历 今天刚在虚拟机上安装好了ubuntu系统,在执行sudo apt install net-tools 命令时报错"没有可用的软件包net-tools,但是它被其他软件包引用&quo ...

  3. EasyUI笔记(二)Layout布局

    本系列只列出一些常用的属性.事件或方法,具体完整知识请查看API文档 Panel(面板)   1. 通过标签创建面板 <div id="p" class="easy ...

  4. 剑指offer-面试题39-数组中出现次数超过一半的数字-抵消法

    /* 题目: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输 ...

  5. Python编辑器——Pycharm以及Sublime Text 3的安装教程

    近来工作繁忙,顾不上学习,但还是有些小兄弟问我有没有编写Python代码的工具以及安装方法,跟我吐槽说他安装后总是有问题.那么今天就来说一说Pycharm的安装,顺带说一下Sublime Text 3 ...

  6. nginx模块之ngx_http_fastcgi_module

    nginx支持LNMP 安装php-fpm yum install php-fpm -y 使用/etc/php-fpm.d/www.conf配置文件默认配置即可 打开php配置: vim /etc/n ...

  7. js限制按钮每隔一段时间才能再次点击

    设置属性 disabled 可以限制交互,单击按钮时添加disabled=“disabled”属性,再为按钮添加定时器,一定时间后删除定时器和disabled属性 <!DOCTYPE html& ...

  8. sqlserver创建和删除外键约束

    x先找出约束名字然后删除它我给个例子 --测试环境--主表create table test1(id int primary key not null,value int)insert test1 s ...

  9. ROS开发--在订阅话题的回调函数中发布话题

    处理激光数据时,需要将处理后的激光数据再发布,需要保持一致的频率,所以必须在回调函数中发布激光数据信息. 代码参考:https://blog.csdn.net/heyijia0327/article/ ...

  10. 5.Docker Compose 部署 Harbor

    什么是 Harbor Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器,通过添加一些企业必需的功能特性,例如安全.标识和管理等,扩展了开源 Docker Dis ...