给一棵$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. 关于Maven项目install时出现No compiler is provided in this environment的处理

    关于Maven项目build时出现No compiler is provided in this environment的处理 新配置的Eclipse环境,运行现有项目没问题,一日,从svn上检出了一 ...

  2. 安卓和html的互相调用

    1.写html和安卓布局 <Button android:id="@+id/btn" android:layout_width="wrap_content" ...

  3. ionic改tab文字和icon图片的颜色

    The official way would be: Change in your theme/variables.scss Active icon for tabs on android is: $ ...

  4. 在linux环境下让java代码生效的步骤

    1.kill jboss 2.compile 3.deploy 4.bootstrap jboss.

  5. 【转载】How long is “too long” for MySQL Connections to sleep?

    From:http://dba.stackexchange.com/questions/1558/how-long-is-too-long-for-mysql-connections-to-sleep ...

  6. centos配置数据源和java环境配置

    ---恢复内容开始--- 一:前言 今天送走了一位同事,看着别人走勾起了我蠢蠢欲动的心啊,但是我知道,我不能那么的任性,我是men,这几天难得的清闲,所以我就弄一弄linux,昨天把网给配通了,今天配 ...

  7. HDU 2084 DP经典例子---数塔问题

    http://acm.hdu.edu.cn/showproblem.php?pid=2084 #include "iostream" #include "cstdio&q ...

  8. 【Foreign】石子游戏 [博弈论]

    石子游戏 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output 输出T行,表示每组的答案. Sample Input 3 ...

  9. HDU1907(尼姆博弈)

    John Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submis ...

  10. ubuntu下wireshark+scapy+tcpreply

    安装wireshark命令: sudo apt-get install wireshark 运行打开wireshark命令: sudo wireshark(一定要以超级权限打开) 正确打开的窗口应该默 ...