异或和(xorsum)

题目大意:定义 F ( { a n } ) F(\{a_n\}) { a n } \{a_n\} 的所有子序列的异或和的和。
给定 n , L , R n,L,R ,要求 a i [ L , R ] a_i\in[L,R] ,求 F ( { a n } ) F(\{a_n\}) 有多少种可能的值。100000组数据, n 100 , L , R 1 0 18 n\le100,L,R\le10^{18}
题解:考虑怎么算F,发现考虑每位的贡献可以知道答案就是 2 n 1 2^{n-1} 乘以所有数字的或。
因此只关心所有数字的或有多少种可能。首先将n=1或者L=R判掉,发现可以用两个数字表示的都可以用恰好两个数字表示。
首先先将l和r的LCP扔掉。
然后考虑令hr表示不超过r的最大的2的次幂,r’=r-hr。
首先l~ (hr-1)和(hr+l)~ (hr+hr-1)都是可以被直接表示。
然后考虑hr~ (hr+l-1)这一段。
首先若r’+1>=l,那这一段仍然全部可以被表示。
否则hr~ (hr+r’)可以被表示,还需要考虑(hr+r’+1)~ (hr+l-1)哪些数可以被表示出来。
不难发现一定是取两个介于hr~ (hr+r’)的数字。
也就是问两个不超过r’的数字或起来,在(r’+1)~ (l-1)之间的数字有多少?
差分后变为两个不超过r’的数字或起来,能得到哪些不超过x的数字?若hr’为不超过r’的最大的2的次幂,那么发现0~ (hr+hr-1)都可以被表示出来,然后和x取min即可。
这样就做完了。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline lint inln() { lint x;scanf("%lld",&x);return x; }
inline int inn() { return int(inln()); }
const int LOG=63;//conclusion : f( {a_n} ) = 2^{n-1} \times OR_{i=1}^n a_i
inline lint h(lint x) { for(int i=LOG;i>=0;i--) if((x>>i)&1) return 1ll<<i;return 0; }
inline lint __solve(lint r,lint x) { return r?min(2*h(r),x+1):min(x+1,1ll); }
inline lint solve(lint r,lint x) { return __solve(r,x)-r-1; }
int main()
{
    for(int T=inn();T;T--)
    {
        int n=inn();lint l=inln(),r=inln();
        if(n==1||l==r) { printf("%lld\n",r-l+1);continue; }
        for(int i=LOG;i>=0;i--)
        {
            int lp=(l>>i)&1,rp=(r>>i)&1;
            if(rp==1&&lp==1) l^=1ll<<i,r^=1ll<<i;
            else if(rp==1&&lp==0) break;
        }
        lint hr=h(r),rp=r^hr;
        if(rp>=l-1) printf("%lld\n",-l+hr+hr);
        else printf("%lld\n",hr-l+rp+1+hr-l+solve(rp,l-1));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/89140030