传送门

题意

分析

f[u]表示u到根的边的异或

树上两点之间的异或值为f[u]^f[v],

然后将查询用莫队算法分块,每个点插入到字典树中,利用字典树维护两点异或值大于等于M复杂度O(N^(3/2)*logM)

参考 _zidaoziyan

表示又陷入查错的大坑,思路是对的,调不出来,留坑

trick

代码

wa
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define F(i,a,b) for(int i=a;i<=b;++i) const int maxn = 50050;//集合中的数字个数
int ch[20*maxn][2];//节点的边信息
int num[20*maxn];//记录节点的使用次数,删除时要用
//int val[32*maxn];//节点存储的值
int cnt;//树中节点的个数 bitset<20>choose;
int ask;
int f[maxn],vis[maxn];
ll ans[maxn];
vector<pair<int,int> >mp[maxn];
struct node
{
int l,r,id,len;
bool operator<(const node &p)const
{
return len==p.len?r<p.r:len<p.len;
}
}a[maxn]; void bfs(int u)
{
queue<int>q;
q.push(1);
mem(vis,0);
vis[1]=1;f[1]=0;
while(!q.empty())
{
int tmp=q.front();q.pop();
for(int i=0;i<mp[tmp].size();++i)
{
int v=mp[tmp][i].first;
if(vis[v]) continue;
f[v]=f[tmp]^mp[tmp][i].second;
q.push(v);vis[v]=1;
}
}
} inline void init()
{
cnt=1;mem(ch[0],0);//清空树
}
/*
void insert(int x)//在字典树中插入x,和一般字典树操作相同,将x化成二进制插入到字典树
{
int cur=0;
for(int i=29;i>=0;--i)
{
int idx=((x>>i)&1);
if(!ch[cur][idx])
{
mem(ch[cnt],0);
num[cnt]=0;
ch[cur][idx]=cnt++;
//val[cnt++]=0;
}
//printf("ch[%d][%d]=%d\n",cur,idx,ch[cur][idx]);
cur=ch[cur][idx];
num[cur]++;
}
//val[cur]=x;//最后节点插入val
}
*/
void update(int x,int c)
{
int cur=0;
for(int i=17;i>=0;--i)
{
int idx=((x>>i)&1);
if(!ch[cur][idx])
{
mem(ch[cnt],0);
num[cnt]=0;
ch[cur][idx]=cnt++;
}
cur=ch[cur][idx];
num[cur]+=c;
}
} /*
ll query(ll x)//在字典树(数集)中查找和x异或是最大值的元素y,返回y
{
int cur=0;
for(int i=32;i>=0;--i)
{
int idx=(x>>i)&1;
if(ch[cur][idx^1]) cur=ch[cur][idx^1];else cur=ch[cur][idx];
}
return val[cur];
}
*/ int query(int x)//返回移动一位增加/减少的匹配数
//带删除操作的查询
{
int cur=0,idx,ans=0;
for(int i=17;i>=0;--i)
{
if((i<<i)&x) idx=1;else idx=0;
if(!choose[i])
{
if(ch[cur][idx^1]) ans+=num[ch[cur][idx^1]];
if((!ch[cur][idx])||(!num[ch[cur][idx]])) return ans;
cur=ch[cur][idx];
}
else
{
if((!ch[cur][idx^1])||(num[ch[cur][idx^1]]==0)) return ans;
cur=ch[cur][idx^1];
}
//printf("%d\n",ret);
//if(ch[cur][idx^1]&&num[ch[cur][idx^1]]) cur=ch[cur][idx^1];else cur=ch[cur][idx];
}
//printf("val(%d)=%d\n",cur,val[cur]);
return ans;
} /*
int get_ans(int x)
{
int cur=0,ret=0;
for(int i=29;i>=0;--i)
{
int idx=(((x>>i)&1)^1);
if(num[ch[cur][idx]]) cur=ch[cur][idx],ret|=(1<<i);
else cur=ch[cur][idx^1];
}
return ret;
}
*/
void solve()
{
int L=1,R=0;
init();
ll tmp=0;
F(i,1,ask)
{
while(R<a[i].r) {R++;tmp+=query(f[R]);update(f[R],1);}
//printf("tmp1=%lld\n",tmp);
while(R>a[i].r) {update(f[R],-1);tmp-=query(f[R]);R--;}
// printf("tmp2=%lld\n",tmp);
while(L<a[i].l) {update(f[L],-1);tmp-=query(f[L]);L++;}
// printf("tmp3=%lld\n",tmp);
while(L>a[i].l) {L--;tmp+=query(f[L]);update(f[L],1);}
//printf("tmp4=%lld\n",tmp);
//printf("%lld\n",tmp);;
ans[a[i].id]=tmp;
}
} int main()
{
int n,m;
while(scanf("%d %d %d",&n,&m,&ask)!=EOF)
{
int u,v,w,sqr=sqrt(n);choose=m;
F(i,1,n) mp[i].clear();
F(i,1,n-1)
{
scanf("%d %d %d",&u,&v,&w);
mp[u].push_back(pair<int,int>{v,w});
mp[v].push_back(pair<int,int>{u,w});
}
bfs(1);
//F(i,1,n) printf("%d%c",f[i],i==n?'\n':' ');
F(i,1,ask)
{
scanf("%d%d",&a[i].l,&a[i].r);
a[i].id=i;a[i].len=a[i].l/sqr;
}
sort(a+1,a+1+ask);
//F(i,1,ask) printf("%d %d %d\n",a[i].l,a[i].r,a[i].id );
solve();
F(i,1,ask) printf("%lld\n",ans[i]);
}
return 0;
}
//ac
#include<bits/stdc++.h>
using namespace std;
const int maxn=50010;
typedef pair<int,int> PI;
vector<PI>G[maxn];
int a[maxn],unit,q;
bitset <20> cnt;
int vis[maxn];
long long ans[maxn]; struct node{
int l,r,id;
}Q[maxn]; bool cmp(node u,node v){
if(u.l/unit!=v.l/unit)
return u.l/unit<v.l/unit;
return u.r<v.r;
} void bfs(int u){
queue<int>Q;
Q.push(1);
memset(vis,0,sizeof(vis));
vis[1]=1;
while(!Q.empty()){
int u=Q.front();
Q.pop();
for(int i=0;i<G[u].size();i++){
int v=G[u][i].first;
if(vis[v])
continue;
a[v]=a[u]^G[u][i].second;
Q.push(v);
vis[v]=1;
}
}
} struct Trie{
int val[maxn*20],next[maxn*20][2];
int sz;
void init(){
sz=1;
memset(next[0],0,sizeof(next[0]));
} void insert(int num,int x){
int u=0,c;
for(int i=17;i>=0;i--){
if((1<<i)&num)
c=1;
else
c=0;
if(!next[u][c])
memset(next[sz],0,sizeof(next[sz])),val[sz]=0,next[u][c]=sz++;
u=next[u][c];
val[u]+=x;
}
} int query(int num){
int ans=0,c,u=0;
for(int i=17;i>=0;i--){
if((1<<i)&num)
c=1;
else
c=0;
if(cnt[i]==0){
if(next[u][c^1])
ans+=val[next[u][c^1]];
if(!next[u][c]||val[next[u][c]]==0)
return ans;
u=next[u][c];
}
else{
if(!next[u][c^1]||val[next[u][c^1]]==0)
return ans;
u=next[u][c^1];
}
// printf("%d\n",ans);
}
return ans;
}
}; Trie trie;
void solve(){
int L=1,R=0;
trie.init();
long long tmp=0;
for(int i=1;i<=q;i++){
while(R<Q[i].r){
R++;
tmp+=trie.query(a[R]);
trie.insert(a[R],1);
}
//printf("tmp1=%lld\n",tmp); while(R>Q[i].r){
trie.insert(a[R],-1);
tmp-=trie.query(a[R]);
R--;
}
//printf("tmp2=%lld\n",tmp);
while(L<Q[i].l){
trie.insert(a[L],-1);
tmp-=trie.query(a[L]);
L++;
}
// printf("tmp3=%lld\n",tmp );
while(L>Q[i].l){
L--;
tmp+=trie.query(a[L]);
trie.insert(a[L],1);
}
// printf("tmp4=%lld\n", tmp);
ans[Q[i].id]=tmp;
}
} int main(){
int n,m;
while(scanf("%d%d%d",&n,&m,&q)!=EOF){
int u,v,w;
for(int i=1;i<=n;i++)
G[i].clear();
for(int i=1;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
G[u].push_back(PI{v,w});
G[v].push_back(PI{u,w});
}
cnt=m;
a[1]=0,unit=sqrt(n);
bfs(1);
// for(int i=1;i<=n;++i) printf("%d%c",a[i],i==n?'\n':' ');
for(int i=1;i<=q;i++){
scanf("%d%d",&Q[i].l,&Q[i].r);
Q[i].id=i;
}
sort(Q+1,Q+q+1,cmp);
// for(int i=1;i<=q;++i) printf("%d %d %d %d\n",Q[i].l,Q[i].r,Q[i].id);
solve();
for(int i=1;i<=q;i++)
printf("%lld\n",ans[i]);
}
return 0;
}

HDU5589:Tree(莫队+01字典树)的更多相关文章

  1. HDU5589 Tree【分块 01字典树】

    HDU5589 Tree 题意: 给出一棵\(N\)个点的树,每条边有边权,每次询问下标为\([L,R]\)区间内的点能选出多少点对,点对之间的路径上的边权异或和大于\(M\) 题解: 对于两点\(u ...

  2. HDU 6191 2017ACM/ICPC广西邀请赛 J Query on A Tree 可持久化01字典树+dfs序

    题意 给一颗\(n\)个节点的带点权的树,以\(1\)为根节点,\(q\)次询问,每次询问给出2个数\(u\),\(x\),求\(u\)的子树中的点上的值与\(x\)异或的值最大为多少 分析 先dfs ...

  3. HDU6191 Query on A Tre【dsu on tree + 01字典树】

    Query on A Tree Problem Description Monkey A lives on a tree, he always plays on this tree. One day, ...

  4. HDU6191 Query on A Tree (01字典树+启发式合并)

    题意: 给你一棵1e5的有根树,每个节点有点权,1e5个询问(u,x),问你子树u中与x异或最大的值是多少 思路: 自下而上启发式合并01字典树,注意合并时清空trie 线段树.字典树这种结构确定的数 ...

  5. HDU6191(01字典树启发式合并)

    Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Othe ...

  6. Chip Factory(01字典树)

    Chip Factory http://acm.hdu.edu.cn/showproblem.php?pid=5536 Time Limit: 18000/9000 MS (Java/Others)  ...

  7. HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)

    Problem Description   Zero and One are good friends who always have fun with each other. This time, ...

  8. 2014百度之星资格赛—— Xor Sum(01字典树)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total ...

  9. AcWing:144. 最长异或值路径(dfs + 01字典树)

    给定一个树,树上的边都具有权值. 树中一条路径的异或长度被定义为路径上所有边的权值的异或和: ⊕ 为异或符号. 给定上述的具有n个节点的树,你能找到异或长度最大的路径吗? 输入格式 第一行包含整数n, ...

随机推荐

  1. C++学习总结3

    链接上一篇日志,C++学习总结2,下面介绍下C++里面的其他内容 虚函数:一个接口,多种方法. 多态:编译时的多态与运行时的多态. 编译时的多态表现为运算符的重载与函数的重载. 运行时的多态表现为使用 ...

  2. vim字符串替换命令

    呜呜老是忘. 这里记录一下,仅仅记录当中日经常使用的最多的命令. :%s/str1/str2/g   替换每一行中全部str1为str2 经常使用! :s/str1/str2/g 替换当前行全部str ...

  3. Java多线程面试题归纳

    1.多线程有哪几种实现方法?举个样例说明下线程的同步. (1)Java多线程有两种实现方式:继承Thread类和实现Runnable接口,Thread就是实现了Runnable接口. 两个最简单的线程 ...

  4. FragmentSharedFabTransition

    https://github.com/lgvalle/FragmentSharedFabTransition

  5. Nova虚拟机启动提示libvirtError

    OpenStack自动化安装基本折腾完毕,装一次大概也就10分钟,但是装完后今天我的虚拟机起不来,经过查找log发 现如下图提示: 已经到这里,说明已经过了nova-sheduler那一关,跟踪一下代 ...

  6. Quartz深入浅出(二)

    Hello Quartz / 本文通过一个简单的样例让大家高速了解Quartz,上手.并了解Quartz内的一些关键对象 如 Scheduler.Job.Trigger.JobExecutionCon ...

  7. Eclipse中设置编码的方法

    Eclipse中设置编码的方式如果要使插件开发应用能有更好的国际化支持,能够最大程度的支持中文输出,则最好使 Java文件使用UTF-8编码.然而,Eclipse工作空间(workspace)的缺省字 ...

  8. js modify local file

    https://stackoverflow.com/questions/4561157/is-it-possible-to-modify-a-html-file-from-which-the-scri ...

  9. UILabel与UIFont的用法和属性的一些总结

    初始化一个UILabel对象,并初始化大小 UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 100) ...

  10. 基于Delphi7 WebService 在Apache发布及Apache使用说明

    基于Delphi7 WebService 在Apache 发布及Apache 使用说明 qq:394251165 前段时间,需要将基于Delphi7 WebService 发布在Apache, 很是苦 ...