2021牛客暑期多校训练营4 Tree Xor (区间异或上一个数+区间求交)

Posted 昵称很长很长真是太好了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021牛客暑期多校训练营4 Tree Xor (区间异或上一个数+区间求交)相关的知识,希望对你有一定的参考价值。

题解:
首先我们可以发现,只要确定了一个值,那么树上其他的值也可以确定下来了,但是显然,遍历一棵树的时间复杂度为O(n),如果枚举+暴力判断的话时间复杂度 O ( 1 e 9 ∗ n ) O(1e9*n) O(1e9n)

看了大佬的题解。
首先可以假设 a [ 1 ] = 0 a[1]=0 a[1]=0,然后求出其他的点分别为 a [ i ] a[i] a[i]
假设我们把 a [ 1 ] a[1] a[1]变成 x x x,那么其他的点也都会被异或上一个 x x x
假设 l [ 1 ] < 0 ⊕ x < r [ 1 ] l[1]<0 \\oplus x<r[1] l[1]<0x<r[1]
那么 l [ 1 ] < a [ i ] ⊕ x < r [ 1 ] l[1]<a[i] \\oplus x<r[1] l[1]<a[i]x<r[1]
也就是 l [ 1 ] ⊕ x < a [ i ] < r [ 1 ] ⊕ x l[1]\\oplus x<a[i]<r[1]\\oplus x l[1]x<a[i]<r[1]x

然后对n个不等式求一个交集即可。
等等…
区间异或x后好像不是连续的…
看了大佬们的题解才明白该如何操作。
有些区间是可以(感觉不好描述)
看这位大佬对其的解释:https://blog.csdn.net/qq_45874328/article/details/119175535

处理完的区间我们可以存到一个vector中,然后求区间交集即可
类似于差分的求法
对每个区间的左端点为l,右端点为r,拆分成{l,1} {r,-1},放进数组中,然后按照第一维进行排序。
排完序后进行遍历,设一个变量为cnt=0,每次加上i.second,若cnt=n时(n为区间个数)计算当前为n的区间长度即可。

 #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")


#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
using namespace std;
const int maxn=5e5+10;
const int MAX=(1<<30)-1;

pair<int,int> pp[maxn];
vector<pair<int,int> > edge[maxn];
vector<pair<int,int> > v;
void query(int start,int ends,int l,int r,int val){
    if(l<=start&&ends<=r){
        int ansl=(start^val)&(((1<<30)-1)-(ends-start));
        int ansr=ansl+(ends-start);
        v.push_back({ansl,1});
        v.push_back({ansr+1,-1});
        return ;
    }
    int mid=(start+ends)>>1;
    if(l<=mid) query(start,mid,l,r,val);
    if(mid<r) query(mid+1,ends,l,r,val);
}
void dfs(int x,int fa,int val){
    query(0,MAX,pp[x].first,pp[x].second,val);
    for(auto i:edge[x]){
        if(i.first==fa) continue;
        dfs(i.first,x,i.second^val);
    }
}
int ans;
int n;
void sol(){
    sort(v.begin(),v.end());
    int cnt=0;
    for(int i=0;i<v.size();i++){
        cnt+=v[i].second;
        if(cnt==n){
            if(i!=v.size()) ans+=v[i+1].first-v[i].first;
        }
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>pp[i].first>>pp[i].second;
    }
    for(int i=1;i<n;i++){
        int x,y,z;
        cin>>x>>y>>z;
        edge[x].push_back({y,z});
        edge[y].push_back({x,z});
    }
    dfs(1,0,0);
    sol();
    cout<<ans<<endl;
}

以上是关于2021牛客暑期多校训练营4 Tree Xor (区间异或上一个数+区间求交)的主要内容,如果未能解决你的问题,请参考以下文章

2021牛客暑期多校训练营4 Tree Xor (区间异或上一个数+区间求交)

2021牛客暑期多校训练营4 Tree Xor (区间异或上一个数+区间求交)

2021牛客暑期多校训练营4

2021牛客暑期多校训练营 4 题解

2021牛客暑期多校训练营4,签到题CFIJ

2021牛客暑期多校训练营2