[Contest20171102]简单数据结构题
给一棵$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]简单数据结构题的更多相关文章
- 简单数据结构题(from 钟子谦——IOI2018集训队自选题)
简单数据结构题(from 钟子谦--IOI2018集训队自选题) 试题描述 给一棵 \(n\) 个点的树,点权开始为 \(0\) ,有 \(q\) 次操作,每次操作是选择一个点,把周围一圈点点权 \( ...
- QDUOJ 一道简单的数据结构题 栈的使用(括号配对)
一道简单的数据结构题 发布时间: 2017年6月3日 18:46 最后更新: 2017年6月3日 18:51 时间限制: 1000ms 内存限制: 128M 描述 如果插入“+”和“1”到 ...
- [LOJ#2326]「清华集训 2017」简单数据结构
[LOJ#2326]「清华集训 2017」简单数据结构 试题描述 参加完IOI2018之后就是姚班面试.而你,由于讨厌物理.并且想成为乔布斯一样的创业家,被成功踢回贵系. 转眼,时间的指针被指向201 ...
- 2019浙大校赛--A--Thanks, TuSimple!(简单模拟题)
这题前三段都是一堆吹爆赞助商的屁话,正式题目在图片下边,一个简单模拟题. 题目大意: 有n个男生,m个女生在进行舞会,其中一部分男生祥和比自己矮的女生跳舞,一部分男生想和比自己高的女生跳舞,一部分女生 ...
- 【Luogu3676】小清新数据结构题(动态点分治)
[Luogu3676]小清新数据结构题(动态点分治) 题面 洛谷 题解 先扯远点,这题我第一次看的时候觉得是一个树链剖分+线段树维护. 做法大概是这样: 我们先以任意一个点为根,把当前点看成是一棵有根 ...
- python学习总结----简单数据结构
mini-web服务器 - 能够完成简单的请求处理 - 使用http协议 - 目的:加深对网络编程的认识.为后面阶段学习web做铺垫 简单数据结构 - 排列组合 import itertools # ...
- 牛客练习赛22-E.简单数据结构1(扩展欧拉定理降幂 +树状数组)
链接:E.简单数据结构1 题意: 给一个长为n的序列,m次操作,每次操作: 1.区间加 2.对于区间,查询 ,一直到- 请注意每次的模数不同. 题解:扩展欧拉定理降幂 对一个数p取log(p)次的 ...
- java算法题每日一练01,java入门简单算法题小练
1.给数组做反序 public class Ak01 { public static void main(String[] args) { int[] a = new int[]{22,48,41,2 ...
- lettcode 上的几道哈希表与链表组合的数据结构题
目录 LRU缓存 LFU缓存 全O(1)的数据结构 lettcode 上的几道哈希表与链表组合的数据结构题 下面这几道题都要求在O(1)时间内完成每种操作. LRU缓存 LRU是Least Recen ...
随机推荐
- webpack 3.8 使用 extract-text-webpack-plugin 3.0 抽取css失败:You may need an appropriate loader to handle this file type.
webpack 3.8.1 使用 extract-text-webpack-plugin 3.0.2 抽取css时失败,报错: ERROR in ./src/static/style/localTim ...
- Educational Codeforces Round 58 (Rated for Div. 2) 题解
Educational Codeforces Round 58 (Rated for Div. 2) 题目总链接:https://codeforces.com/contest/1101 A. Min ...
- 7月16号day8总结
今天学习过程和小结 1.列举Linux常用命令 shutdown now Linux关机 rebot重启 mkdir mkdir -p递归创建 vi/touth filename rm -r file ...
- VC遍历窗体控件的实现
最近在写控制台,在设计界面按钮风格时不想通过每个按钮的ID来获取其句柄,而是通过遍历窗体所有控件,然后判断其控件类型进而来实现. 代码如下: // 遍历得到页面中的所有Button控件,依次设定其样式 ...
- ORACLE中根据生日得到年龄
create or replace function F_GETAGE(dateofbirth date) return varchar2 is begin ) then ); else ) then ...
- Java并发(8)- 读写锁中的性能之王:StampedLock
在上一篇<你真的懂ReentrantReadWriteLock吗?>中我给大家留了一个引子,一个更高效同时可以避免写饥饿的读写锁---StampedLock.StampedLock实现了不 ...
- 查看jar包源码
1.Maven项目 如下图设置后,它会自动下载源文件,这样就能看到了 2.传统Java项目 2.1.安装 Jad 下载 Jad :http://varaneckas.com/jad/ 解压到任意目录即 ...
- bzoj 1412 最小割 网络流
比较明显的最小割建模, 因为我们需要把狼和羊分开. 那么我们连接source和每个羊,流量为inf,代表这条边不能成为最小割中的点,同理连接每个狼和汇,流量为inf,正确性同上,那么对于每个相邻的羊和 ...
- 平衡树之splay讲解
首先来说是splay是二叉搜索树,它可以说是线段树和SBT的综合,更可以解决一些二者解决不了的问题,splay几乎所有的操作都是由splay这一操作完成的,在介绍这一操作前我们先介绍几个概念和定义 二 ...
- 4.flume实战(一)
需求:从指定网络端口采集数据输出到控制台 使用flume的关键就是写配置文件 a)配置source b)配置channel c)配置sink d)把以上三个组件串起来 我们看一下官网给的配置文件 # ...