hdu_5589_Tree(莫队+字典树)
题目连接:hdu_5589_Tree
题意:给你一棵树和一些边值,n个点n-1条边,一个m,q个询问,每个询问让你输出在[l,r]区间内任意两点树上的路径的边权异或的和大于m的点对数。
题解:这题很巧妙,看数据知道要用莫队,不过如何来处理树上任意两点的边权异或和大于m呢?我们知道,一个数和另一个数异或两次等于自己,如果我们记录所有的点都与1这个点的路径异或和,不就可以得出任意两点的路径异或和了吗,然后如果我们要用莫队,就要找到增加,删除的时候答案对应的变化,要支持增加删除,并且要找比m大的异或值,01字典树是一个不错的选择,我们考虑如果要找比m大的数,那么在二进制下,前面的位肯定都相同,后面的某一位m为0,当前数为1才有比m大,我们在将异或和插入字典树的时候,转换为二进制,从高位开始插,每插一位,当前的cnt++,表示在当前位为0或者1的数有一个,删除的时候就对应cnt--就行了。
询问:这里设即将插入的数为节点x到1的节点的异或值为sum,我们要和m相比,因为要找比m大的数,而我们此时插入的都是当前节点到根节点的异或和,这里我们就要用到贪心的思想,从高位开始找,当m的当前位为1时,此时你只能找字典树中为与sum当前位异或为1的,如果不找与sum当前位异或为1的那你后面的位无论怎么找,都不能大于m,要与sum当前位异或为1,当sum的当前位为0,应找1这个子节点,当sum当前位为1,应找0这个子节点,所以就是当m的当前位为1时,下一个子节点应为(sum的当前位^1),当m的当前位为0时,直接加上与sum当前位异或为1的子节点的cnt,因为到这一位的时候,与sum当前位异或为1,那后面位与sum异或完后必然是大于m的,所以直接加上当前与sum异或为1的子节点的cnt就行了,然后我们继续搜寻与sum当前为异或为0的下一位,和上面一样,要使与sum当前位异或为0,sum当前位^0=sum当前位。
最后莫队处理完就是结果了
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define F(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
const int N=;
int M[],va[N],sqr,n,m,k,x,y,z;
LL ans[N];
struct query{
int l,r,id,sq;
bool operator<(const query & b)const{
if(sq==b.sq)return r<b.r;
return sq<b.sq;
}
}q[N];
//-------------------------树的处理-----------------
int g[N],nxt[N<<],w[N<<],v[N<<],eda;
inline void adg(int x,int y,int z){v[++eda]=y,w[eda]=z,nxt[eda]=g[x],g[x]=eda;} void dfs(int u=,int pre=){
for(int i=g[u];i;i=nxt[i])
if(v[i]!=pre)va[v[i]]=w[i]^va[u],dfs(v[i],u);
}
//----------------字典树----------------------------
struct Trie{
int sum[N*][],cnt[N*],ed,c,mc;
void init(){ed=cnt[]=,sum[][]=sum[][]=;}
void insert(int x,int now=){
for(int i=;i>=;i--){
c=x>>i&;
if(!sum[now][c])
sum[now][c]=++ed,cnt[ed]=,sum[ed][]=sum[ed][]=;
now=sum[now][c],cnt[now]++;
}
}
void del(int x,int now=){
for(int i=;i>=;i--)c=x>>i&,now=sum[now][c],cnt[now]--;
}
LL ask(int x,int now=,LL ans=){
for(int i=;i>=;i--){
c=x>>i&,mc=M[i];
if(mc)now=sum[now][c^];
else ans+=cnt[sum[now][c^]],now=sum[now][c];
if(!now)return ans;
}
return ans;
}
}tr; void modui(){
sort(q+,q++k);
int l=,r=;LL ret=;
F(i,,k){
while(r<q[i].r)r++,ret+=tr.ask(va[r]),tr.insert(va[r]);
while(l>q[i].l)l--,ret+=tr.ask(va[l]),tr.insert(va[l]);
while(r>q[i].r)tr.del(va[r]),ret-=tr.ask(va[r]),r--;
while(l<q[i].l)tr.del(va[l]),ret-=tr.ask(va[l]),l++;
ans[q[i].id]=ret;
}
} int main(){
while(~scanf("%d%d%d",&n,&m,&k)){
sqr=(int)sqrt(n);
for(int ee=;ee<=;ee++)M[ee]=(m>>ee)&;
memset(g,,sizeof(g)),eda=;
F(i,,n-)scanf("%d%d%d",&x,&y,&z),adg(x,y,z),adg(y,x,z);
F(i,,k)scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i,q[i].sq=q[i].l/sqr;
dfs(),tr.init(),modui();
F(i,,k)printf("%lld\n",ans[i]);
}
return ;
}
hdu_5589_Tree(莫队+字典树)的更多相关文章
- Codeforces 666E E - Forensic Examination SA + 莫队 + 线段树
E - Forensic Examination 我也不知道为什么这个复杂度能过, 而且跑得还挺快, 数据比较水? 在sa上二分出上下界, 然后莫队 + 线段树维护区间众数. #include< ...
- 洛谷P3246 序列 [HNOI2016] 莫队/线段树+扫描线
正解:莫队/线段树+扫描线 解题报告: 传送门! 似乎是有两种方法的,,,所以分别港下好了QAQ 第一种,莫队 看到这种询问很多区间之类的就会自然而然地想到莫队趴?然后仔细思考一下,发现复杂度似乎是欧 ...
- 【bzoj3289】Mato的文件管理 离散化+莫队算法+树状数组
原文地址:http://www.cnblogs.com/GXZlegend/p/6805224.html 题目描述 Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份 ...
- HDU6534 Chika and Friendly Pairs(莫队,树状数组)
HDU6534 Chika and Friendly Pairs 莫队,树状数组的简单题 #include<bits/stdc++.h> using namespace std; cons ...
- BZOJ 3289: Mato的文件管理[莫队算法 树状数组]
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2399 Solved: 988[Submit][Status][Di ...
- BZOJ3289 Mato的文件管理(莫队算法+树状数组)
题目是区间逆序数查询. 莫队算法..左或右区间向左或右延伸时加或减这个区间小于或大于新数的数的个数,这个个数用树状数组来统计,我用线段树超时了.询问个数和数字个数都记为n,数字范围不确定所以离散化,这 ...
- 洛谷P4689 [Ynoi2016]这是我自己的发明(莫队,树的dfn序,map,容斥原理)
洛谷题目传送门 具体思路看别的题解吧.这里只提两个可能对常数和代码长度有优化的处理方法. I 把一个询问拆成\(9\)个甚至\(16\)个莫队询问实在是有点珂怕. 发现询问的一边要么是一个区间,要么是 ...
- 「洛谷1903」「BZOJ2120」「国家集训队」数颜色【带修莫队,树套树】
题目链接 [BZOJ传送门] [洛谷传送门] 题目大意 单点修改,区间查询有多少种数字. 解法1--树套树 可以直接暴力树套树,我比较懒,不想写. 稍微口胡一下,可以直接来一个树状数组套主席树,也就是 ...
- 【CF633H】Fibonacci-ish II 莫队+线段树
[CF633H]Fibonacci-ish II 题意:给你一个长度为n的序列$a_i$.m个询问,每个询问形如l,r:将[l,r]中的所有$a_i$排序并去重,设得到的新数列为$b_i$,求$b_1 ...
随机推荐
- 安装vb6 正在更新系统 无响应
新装的win10系统,安装vb6时,最后一直卡在“正在更新系统”,程序无响应,没办法,kill掉后,貌似不影响软件使用,但是安装vs6sp6B无法成功安装. 解决办法是: 不安装“数据访问”组件. 参 ...
- 九、oracle 事务
一.什么是事务事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml(数据操作语言,增删改,没有查询)语句要么全部成功,要么全部失败.如:网上转账就是典型的要用事务来处理,用于保证数据的 ...
- Orace内置函数大全[转:http://www.cnblogs.com/lfx0692/articles/2395950.html]
NewProgramer Oracle SQL 内置函数大全(转) SQL中的单记录函数 1.ASCII 返回与指定的字符对应的十进制数;SQL> select ascii('A') A,a ...
- Android任务栈TaskStack
Task:有多个Activity按顺序组成的一个完整的业务逻辑. 任务栈(TaskStack):新增的Activity放入栈中,点击back栈顶Activity从栈中退出. android:nohis ...
- 巧用weui.topTips验证数据
场景一.有一个输入金额的场景,这个金额需要验证,验证说明如下: 不能为空格: 不能为0: 不能为汉字: 不能为其它字符: 不能大于200: 唯一可以的是,只有输入3~199之间的数字,下面的确定按钮才 ...
- 调试MVC项目,不关闭 IIS EXPRESS
在VS主面板打开:工具->选项->调试->编辑继续 取消选中[启用"编辑并继续"] 就OK了 (英文版的请对应相应的操作) 不过这是针对所有的调试,如果你想针 ...
- CSS3秘笈:第七章
第七章 margin.padding和border 1.盒模型:四个属性: (1)padding:内容与其边框线之间的空间. (2)border:盒子周围的直线 (3)background-colo ...
- js基础和工具库
/* * 作者: 胡乐 * 2015/4/18 * js 基础 和 工具库 * * * */ //根据获取对象 function hGetId(id){ return document.getElem ...
- tomcat 高并发配置 与优化
公司的一个服务器使用Tomcat6默认配置,在后台一阵全点击服务器就报废了,查了一下就要是PERMSIZE默认值过小造成(16-64) TOMCAT_HOME/bin/catalina.sh 添加一行 ...
- 在C#中使用反射调用internal的方法
MSDN上解释Internal如下: The internal keyword is an access modifier for types and type members. Internal t ...