给一棵$n$个点的数,点权开始为$0$,有$q$次操作,每次操作选择一个点,把周围一圈点点权$+1$,在该操作后你需要输出当前周围一圈点点权的异或和。

由于输出量较大,设第$i$个询问输出为$ans_i$,你只需要输出$\sum\limits_{i=1}^qans_i(i^2+i)\mod (10^9+7)$

异或和的话,用trie存比较方便

具体点:每个节点建一棵trie,存它的所有儿子的权值,trie上的tag维护数字数量和当前子树内的异或和

①对所有儿子$+1$

其实就是把一棵trie中的所有数字$+1$

为了模拟加法,我们的trie是从低位开始建的

当前位可能是$0$或$1$,如果是$0$,$+1$后会变成$1$,如果是$1$,$+1$后会变成$0$并进位

那么我们直接交换当前trie节点的左右儿子,并递归进入$0$儿子

修改过程中顺便维护异或和

②对父亲$+1$

为了知道一个节点当前的值,我们需要两个标记

$d_{x}$表示节点$x$的增值

$ds_x$表示节点$x$的所有儿子的增值

那么一个节点当前的值就是$d_x+ds_{fa_x}$

所以我们对$x$的父亲$+1$时,只需要在$fa_{fa_x}$的trie中删除$d_{fa_x}$,让$d_x+1$,然后再插入回去

于是就愉快地解决啦

#include<stdio.h>
#define ll long long
struct edge{
	int to,nex;
}e[1000010];
int h[500010],d[500010],sd[500010],fa[500010],root[500010],ch[20000010][2],siz[20000010],xorsum[20000010],tot;
void add(int a,int b){
	tot++;
	e[tot].to=b;
	e[tot].nex=h[a];
	h[a]=tot;
}
void pushup(int x){
	xorsum[x]=((xorsum[ch[x][0]]^xorsum[ch[x][1]])<<1)|(siz[ch[x][1]]&1);
}
void insert(int&x,int v,int p){
	if(x==0){
		tot++;
		x=tot;
	}
	siz[x]++;
	if(p==19)return;
	insert(ch[x][(v>>p)&1],v,p+1);
	pushup(x);
}
void dfs(int x){
	for(int i=h[x];i;i=e[i].nex){
		if(e[i].to!=fa[x]){
			fa[e[i].to]=x;
			dfs(e[i].to);
			insert(root[x],0,0);
		}
	}
}
void swap(int&a,int&b){a^=b^=a^=b;}
void plus(int x,int p){
	if(x==0||p==19)return;
	swap(ch[x][0],ch[x][1]);
	plus(ch[x][0],p+1);
	pushup(x);
}
void erase(int&x,int v,int p){
	siz[x]--;
	if(p==19){
		if(siz[x]==0)x=0;
		return;
	}
	erase(ch[x][(v>>p)&1],v,p+1);
	if(siz[x]==0)
		x=0;
	else
		pushup(x);
}
ll query(int x){
	sd[x]++;
	plus(root[x],0);
	if(x==1)return xorsum[root[x]];
	if(fa[x]==1){
		d[1]++;
		return xorsum[root[x]]^d[1];
	}
	erase(root[fa[fa[x]]],d[fa[x]]+sd[fa[fa[x]]],0);
	d[fa[x]]++;
	insert(root[fa[fa[x]]],d[fa[x]]+sd[fa[fa[x]]],0);
	return xorsum[root[x]]^(d[fa[x]]+sd[fa[fa[x]]]);
}
int main(){
	int n,q,i,a,b;
	ll ans=0;
	scanf("%d%d",&n,&q);
	for(i=1;i<n;i++){
		scanf("%d%d",&a,&b);
		add(a,b);
		add(b,a);
	}
	tot=0;
	dfs(1);
	for(i=1;i<=q;i++){
		scanf("%d",&a);
		ans=(ans+query(a)*(i*(ll)i+(ll)i))%1000000007;
	}
	printf("%lld",ans);
}

[Contest20171102]简单数据结构题的更多相关文章

  1. 简单数据结构题(from 钟子谦——IOI2018集训队自选题)

    简单数据结构题(from 钟子谦--IOI2018集训队自选题) 试题描述 给一棵 \(n\) 个点的树,点权开始为 \(0\) ,有 \(q\) 次操作,每次操作是选择一个点,把周围一圈点点权 \( ...

  2. QDUOJ 一道简单的数据结构题 栈的使用(括号配对)

    一道简单的数据结构题 发布时间: 2017年6月3日 18:46   最后更新: 2017年6月3日 18:51   时间限制: 1000ms   内存限制: 128M 描述 如果插入“+”和“1”到 ...

  3. [LOJ#2326]「清华集训 2017」简单数据结构

    [LOJ#2326]「清华集训 2017」简单数据结构 试题描述 参加完IOI2018之后就是姚班面试.而你,由于讨厌物理.并且想成为乔布斯一样的创业家,被成功踢回贵系. 转眼,时间的指针被指向201 ...

  4. 2019浙大校赛--A--Thanks, TuSimple!(简单模拟题)

    这题前三段都是一堆吹爆赞助商的屁话,正式题目在图片下边,一个简单模拟题. 题目大意: 有n个男生,m个女生在进行舞会,其中一部分男生祥和比自己矮的女生跳舞,一部分男生想和比自己高的女生跳舞,一部分女生 ...

  5. 【Luogu3676】小清新数据结构题(动态点分治)

    [Luogu3676]小清新数据结构题(动态点分治) 题面 洛谷 题解 先扯远点,这题我第一次看的时候觉得是一个树链剖分+线段树维护. 做法大概是这样: 我们先以任意一个点为根,把当前点看成是一棵有根 ...

  6. python学习总结----简单数据结构

    mini-web服务器 - 能够完成简单的请求处理 - 使用http协议 - 目的:加深对网络编程的认识.为后面阶段学习web做铺垫 简单数据结构 - 排列组合 import itertools # ...

  7. 牛客练习赛22-E.简单数据结构1(扩展欧拉定理降幂 +树状数组)

    链接:E.简单数据结构1 题意: 给一个长为n的序列,m次操作,每次操作: 1.区间加 2.对于区间,查询 ,一直到- 请注意每次的模数不同.   题解:扩展欧拉定理降幂 对一个数p取log(p)次的 ...

  8. java算法题每日一练01,java入门简单算法题小练

    1.给数组做反序 public class Ak01 { public static void main(String[] args) { int[] a = new int[]{22,48,41,2 ...

  9. lettcode 上的几道哈希表与链表组合的数据结构题

    目录 LRU缓存 LFU缓存 全O(1)的数据结构 lettcode 上的几道哈希表与链表组合的数据结构题 下面这几道题都要求在O(1)时间内完成每种操作. LRU缓存 LRU是Least Recen ...

随机推荐

  1. Android中使用RadioButton代替ImageButton

    画外音————好久没上来发文章了,这几个月一直忙着一些跟编程不沾边的事,拖了好久,现在还在持续中,顺利的话7月份应该能解放了..今天偶尔上来写一段番外篇性质的心得发现. 之前搞的Android项目,作 ...

  2. win7---虚拟wifi无法启动承载网络

    转载自:http://nbbbs.zol.com.cn/40/32108_397955.html 解决方案:控制面板→硬件和声音→电源选项→更改计划设置→更改高级电源设置→无线适配器设置→节能模式,改 ...

  3. c++ fstream用法

    今天介绍一个复制 粘贴的函数,用fstream实现 #include "stdafx.h" #include<iostream> #include<fstream ...

  4. Nios II 中的缓存和内存数据的读写

    nios 使用地址中31bit来表示访问是否bypass cache.如果bit 31=0 表示不bypass cache,即使用cache里的数据:如果bit 31=1表示bypass cache, ...

  5. [bzoj3524==bzoj2223][Poi2014]Couriers/[Coci 2009]PATULJCI——主席树+权值线段树

    题目大意 给定一个大小为n,每个数的大小均在[1,c]之间的数列,你需要回答m个询问,其中第i个询问形如\((l_i, r_i)\),你需要回答是否存在一个数使得它在区间\([l_i,r_i]\)中出 ...

  6. mongoDB的文档查询

    1.简单查询: find() 方法以非结构化的方式来显示所有文档. 语法 MongoDB 查询数据的语法格式如下:      collection是集合名字,注意应该是当前数据库的集合,collect ...

  7. 用python写爬虫笔记(一)

    https://bitbucket.org/wswp/code   http://example.webscraping.com http://www.w3schools.com selenium.g ...

  8. VS mfc MessageBox() 使用英文显示

    转载:http://blog.csdn.net/guoyk1990/article/details/44337249 由于特殊原因我们需要将 MessageBox 或 Dialog 的按钮“确定”.“ ...

  9. Shell 脚本实现TCP/UDP协议通讯

    Shell 脚本实现TCP/UDP协议通讯 http://www.cnblogs.com/occult/archive/2012/12/25/2832183.html  

  10. [ Openstack ] OpenStack-Mitaka 高可用之 镜像服务(glance)

    目录 Openstack-Mitaka 高可用之 概述    Openstack-Mitaka 高可用之 环境初始化    Openstack-Mitaka 高可用之 Mariadb-Galera集群 ...