题目链接

https://ac.nowcoder.com/acm/contest/368/F

思路

询问可以离线。

然后每个节点上建32个权值线段树(权值不大,其实只要20颗)

记录每一位权值为x(如果是根节点的话)的01和

然后从根节点向上合并。

访问到需要访问的就查询。

大体这样,不过细节和处理极其恶心(毒瘤mjt或者我码力太差)

合并的时候。

因为两个数字相同要,合并到底的时候要这样.

        if(!siz[a]&&!siz[b]) return a;
if(siz[a]==siz[b]) {
for(int i=0;i<=20;++i) xo[a][i]=0;
siz[a]=0;siz[b]=0;
} else {
for(int i=0;i<=20;++i) xo[a][i]=(bool)((1<<i)&l);
siz[a]=1,siz[b]=0;
}
return a;

因为要异或上x,所以就要讨论子树中0的个数,因为出现两个的树的删去了,还要维护siz

空间\时间复杂度是\(nlog^2\)

代码

/*
询问可以离线。
然后每个节点上建32个权值线段树(权值不大,其实只要20颗)
记录每一位权值为x(如果是根节点的话)的01和
然后从根节点向上合并。
访问到需要访问的就查询。
大体这样,不过细节和处理极其恶心(毒瘤mjt或者我码力太差)
合并的时候。
因为两个数字相同要,合并到底的时候要这样
if(!siz[a]&&!siz[b]) return a;
if(siz[a]==siz[b]) {
for(int i=0;i<=20;++i) xo[a][i]=0;
siz[a]=0;siz[b]=0;
} else {
for(int i=0;i<=20;++i) xo[a][i]=(bool)((1<<i)&l);
siz[a]=1,siz[b]=0;
}
return a;
因为要异或上x,所以就要讨论子树中0的个数,因为出现两个的树的删去了,还要维护siz
空间\时间复杂度是$nlog^2$
*/
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
vector<int> G[N];
int n,m,w[N],cnt;
long long ans[N];
vector<pair<int,int> > Q[N];
int ls[N*20],rs[N*20],xo[N*20][21],rt[N*20],siz[N*20];
void pushup(int rt) {
for(int i=0;i<=20;++i)
xo[rt][i]=xo[ls[rt]][i]+xo[rs[rt]][i];
siz[rt]=siz[ls[rt]]+siz[rs[rt]];
}
int zibi;
int merge(int l,int r,int a,int b) {
if(!a||!b) return a+b;
if(l==r) {
if(!siz[a]&&!siz[b]) return a;
if(siz[a]==siz[b]) {
for(int i=0;i<=20;++i) xo[a][i]=0;
siz[a]=0;siz[b]=0;
} else {
for(int i=0;i<=20;++i) xo[a][i]=(bool)((1<<i)&l);
siz[a]=1,siz[b]=0;
}
return a;
}
int mid=(l+r)>>1;
ls[a]=merge(l,mid,ls[a],ls[b]);
rs[a]=merge(mid+1,r,rs[a],rs[b]);
pushup(a);
return a;
}
void insert(int &now,int l,int r,int k) {
now=++cnt;
if(l==r) {
for(int i=0;i<=20;++i) xo[now][i]=(bool)((1<<i)&k);
siz[now]=1;
return;
}
int mid=(l+r)>>1;
if(k<=mid) insert(ls[now],l,mid,k);
else insert(rs[now],mid+1,r,k);
pushup(now);
}
int query(int l,int r,int k,int dep,int rt) {
if(!rt||r<=k) return 0;
if(l>k) return xo[rt][dep];
int mid=(l+r)>>1;
// int ans=0;
if(k<=mid) return query(mid+1,r,k,dep,rs[rt])+query(l,mid,k,dep,ls[rt]);
// if(k>mid)
return query(mid+1,r,k,dep,rs[rt]);
}
int query_siz(int l,int r,int k,int rt) {
if(!rt||r<=k) return 0;
if(l>k) return siz[rt];
int mid=(l+r)>>1;
// int ans=0;
if(k<=mid) return query_siz(mid+1,r,k,rs[rt])+query_siz(l,mid,k,ls[rt]);
// if(k>mid)
return query_siz(mid+1,r,k,rs[rt]);
}
void dfs(int u,int f) {
insert(rt[u],1,n,w[u]);
for(vector<int>::iterator it=G[u].begin();it!=G[u].end();++it) {
if(*it==f) continue;
dfs(*it,u);
rt[u]=merge(1,n,rt[u],rt[*it]);
}
for(vector<pair<int,int> >::iterator it=Q[u].begin();it!=Q[u].end();++it) {
for(int i=0;i<=20;++i) {
int js=query_siz(1,n,it->first,rt[u]);
if(it->first&(1<<i)) {
ans[it->second]+=(1LL<<i)*(long long)(js-query(1,n,it->first,i,rt[u]));
} else {
ans[it->second]+=(1LL<<i)*(long long)query(1,n,it->first,i,rt[u]);
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&w[i]);
for(int i=2;i<=n;++i) {
int a,b;
scanf("%d%d",&a,&b);
G[a].push_back(b);
G[b].push_back(a);
}
for(int i=1;i<=m;++i) {
int u,x;
scanf("%d%d",&u,&x);
Q[u].push_back(make_pair(x,i));
}
dfs(1,0);
for(int i=1;i<=m;++i) printf("%lld\n",ans[i]);
return 0;
}

牛客竞赛&&mjt的毒瘤赛的更多相关文章

  1. 2020牛客竞赛 DP F 碎碎念

    作者:儒生雄才1链接:https://ac.nowcoder.com/discuss/366644来源:牛客网 题目连接:https://ac.nowcoder.com/acm/contest/300 ...

  2. nowcoder(牛客网)提高组模拟赛第一场 解题报告

    T1 中位数(二分) 这个题是一个二分(听说是上周atcoder beginner contest的D题???) 我们可以开一个数组b存a,sort然后二分b进行check(从后往前直接遍历check ...

  3. 题解——牛客网OI赛制测试赛2

    T1 规律题 考虑先全部选中再去重即可 #include <cstdio> #include <algorithm> #include <cstring> #inc ...

  4. nowcoder(牛客网)提高组模拟赛第四场 解题报告

    T1 动态点分治 就是模拟..... 但是没有过!! 看了题解之后发现.... 坑点:有可能 \(x<=r\),但是

  5. 牛客网提高组模拟赛第七场 T3 洞穴(附bitset介绍)

    就是DP. 我们可以很简单的想到要枚举中间点,进行边数的转移. 但是因为边长数据范围很大,所以我们考虑log的倍增. 状态设计为\(dp[i][j][k]\),为从节点\(i\)走\(2^k\)步能否 ...

  6. 牛客网提高组模拟赛第七场 T2 随机生成树

    其实看懂题就很水啦qwq,就是求\(1-N\)的约数啦. 暴力求的话时间复杂度是\(O(NlogN)\)的,其实正解是枚举每个数的倍数......这样的时间复杂度是\(\frac{N}{1}+\fra ...

  7. 牛客网提高组模拟赛第五场 T1同余方程(异或)(位运算)

    区间不好做,但是我们可以转化成前缀来做.转化为前缀之后之后就是二维前缀和. 但是我还是不怎么会做.所以只能去看吉老师的题解 (确定写的那么简单真的是题解???). 我们要求模一个数余0,就等于找它的倍 ...

  8. nowcoder(牛客网)普及组模拟赛第一场 解题报告

    蒟蒻我可能考了一场假试 T1 绩点 这题没什么好说的,应该是只要会语言的就会做. T2 巨大的棋盘 一个模拟题吧qwq,但是要注意取模的时候先加上n或者m再取模,要不然会错的. #include< ...

  9. 牛客竞赛-Who killed Cock Robin

    Who killed Cock Robin? I, said the Sparrow, With my bow and arrow,I killed Cock Robin. Who saw him d ...

随机推荐

  1. binTreepreorderTraversal二叉树前序遍历

    原题 Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binar ...

  2. 详解tween.js 中文使用指南

    补间(动画)是一个概念,允许你以平滑的方式更改对象的属性.你只需告诉它哪些属性要更改,当补间结束运行时它们应该具有哪些最终值,以及这需要多长时间,补间引擎将负责计算从起始点到结束点的值. 例如,pos ...

  3. cmd下 mysql操作命令大全详解

    启动:net start mySql; 进入:mysql -u root -p/mysql -h localhost -u root -p databaseName; 列出数据库:show datab ...

  4. jQuery选择器--:eq(index)、:lt(index)和:gt(index)

       :eq(index) 概述 匹配一个给定索引值的元素 参数 index  从 0 开始计数    :gt(index) 概述 匹配所有大于给定索引值的元素 参数 index  从 0 开始计数 ...

  5. Java基础语法(二 )

    五.运算符 *算术运算符 *赋值运算符 *关系运算符 *逻辑运算符 *位运算符 *三目运算符 算术运算符 *+,-,*,/都是比较简单的操作 *+的几种作用: 加法 正数 字符串连接符 *除法的时候要 ...

  6. MySQL超时配置

    connect_timeout:连接响应超时时间.服务器端在这个时间内如未连接成功,则会返回连接失败. wait_timeout:连接空闲超时时间.与服务器端无交互状态的连接,直到被服务器端强制关闭而 ...

  7. 转:判断Caps Lock键是否打开,如果打开则关闭

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. centos 6.8 配置csh的shell和环境变量

    1.查看shell 查看系统中安装的所有版本的shell:cat   /etc/shells 查看当前用户使用的shell:echo $SHELL 2.修改用户shell 可以在/etc/passwd ...

  9. tomcat9 性能调优

    官网最靠谱 tomcat 参数官网: http://tomcat.apache.org/tomcat-7.0-doc/config/http.html   <Connector   port=& ...

  10. python内置函数的简单使用和介绍

    """内置函数的简单使用和介绍参考链接:https://docs.python.org/3/library/functions.html ""&quo ...