题解 T1
没做出来自闭了
首先找性质:
- 关于一个序列所有子序列的异或和之和:
考虑每一位的贡献,发现若存在一个数这一位是 1,则它一定会贡献 \(2^{n-1}\) 次
证明(令这一位为 1 的有 \(x(x>0)\) 个):
\(\operatorname{contribution}=2^{n-x}\sum\limits_{i=0}^x[2\nmid i]\binom{x}{i}=2^{n-1}\)
最后一步是怎么过来的呢?考虑前 \(n-1\) 位任选,通过调整最后一位满足 \([2\nmid i]\) 的限制
调整与否一定是一个满足一个不满足,得证
然后可以发现 \(n>2\) 是没用的,当做 \(n=2\) 即可
现在问题变为选出 \(x, y\in[l, r]\),问 \(x\or y\) 的取值个数
AGC015D A or...or B Problem
做法是考虑这个 l,r
令其最高不同位为 \(2^k\),高于这一位的部分都去掉
则 \([l, 2^k)\) 内的数能或出来的范围仍在 \([l, 2^k)\)
然后令 \(2^t\) 为 \(r\) 的次高位,则 \([2^k, r]\) 内的数能或出来的范围为 \([2^k, 2^k+2^{t+1})\)
考虑 \([l, 2^k)\) 和 \([2^k, r]\) 交互能或出来的东西
等价于去掉第 \(k\) 位求 \([0, r], [l, 2^k)\) 能或出的范围
因为取或后不可能变小,所以 \([r, l]\) 这一段不能或出
所以就可以算范围了
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n, l, r;
namespace force{
int a[N];
int uni[N], usiz;
int calc() {
int lim=1<<n, sum=0;
for (int s=0; s<lim; ++s) {
int tem=0;
for (int i=1; i<=n; ++i) if (s&(1<<(i-1))) tem^=a[i];
sum+=tem;
}
return sum;
}
void dfs(int u) {
if (u>n) {uni[++usiz]=calc(); return ;}
for (int i=l; i<=r; ++i) a[u]=i, dfs(u+1);
}
void solve() {
usiz=0;
dfs(1);
sort(uni+1, uni+usiz+1);
usiz=unique(uni+1, uni+usiz+1)-uni-1;
cout<<usiz<<endl;
}
}
namespace task{
void solve() {
ll ans=0;
if (l==r) {puts("1"); return ;}
int x=1ll<<(63-__builtin_clzll(l^r));
// cout<<"x: "<<x<<endl;
l&=x-1; r&=x-1;
ans+=x-l;
int r1=0;
if (r) r1=(1ll<<(64-__builtin_clzll(r)))-1;
// cout<<"r1: "<<r1<<endl;
ans+=r1+1; ans+=x-l;
if (r1>=l) ans-=r1-l+1;
printf("%lld\n", ans);
}
}
signed main()
{
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
int T=read();
while (T--) {
n=read(); l=read(); r=read();
if (n==1) printf("%lld\n", r-l+1);
else task::solve();
// else force::solve();
}
return 0;
}