Bessie has been procrastinating on her cow-mistry homework and now needs your help! She needs to create a mixture of three different cow-michals. As all good cows know though, some cow-michals cannot be mixed with each other or else they will cause an explosion. In particular, two cow-michals with labels aa and bb can only be present in the same mixture if a⊕b≤Ka⊕b≤K (1≤K≤1091≤K≤109).
NOTE: Here, a⊕ba⊕b denotes the "bitwise exclusive or'' of non-negative integers aa and bb. This operation is equivalent to adding each corresponding pair of bits in base 2 and discarding the carry. For example,
Bessie has NN (1≤N≤2⋅1041≤N≤2⋅104) boxes of cow-michals and the ii-th box contains cow-michals labeled lili through riri inclusive (0≤li≤ri≤109)(0≤li≤ri≤109). No two boxes have any cow-michals in common. She wants to know how many unique mixtures of three different cow-michals she can create. Two mixtures are considered different if there is at least one cow-michal present in one but not the other. Since the answer may be very large, report it modulo 109+7109+7.
The first line contains two integers NN and KK.Each of the next NN lines contains two space-separated integers lili and riri. It is guaranteed that the boxes of cow-michals are provided in increasing order of their contents; namely, ri<li+1ri<li+1 for each 1≤i<N1≤i<N.
The number of mixtures of three different cow-michals Bessie can create, modulo 109+7109+7.
1 13 0 199
4280
We can split the chemicals into 13 groups that cannot cross-mix: (0…15)(0…15), (16…31)(16…31), …… (192…199)(192…199). Each of the first twelve groups contributes 352352 unique mixtures and the last contributes 5656 (since all (83)(83) combinations of three different cow-michals from (192…199)(192…199) are okay), for a total of 352⋅12+56=4280352⋅12+56=4280.
6 147 1 35 48 103 125 127 154 190 195 235 240 250
267188
Problem credits: Benjamin Qi
[/hide]
(Analysis by Benjamin Qi)
Note: I used the first sample case as a problem in a math competition a while ago.
First, add one to KK and change ≤≤ to <<. Then define PP to be the smallest power of two greater than KK. Every triangle must satisfy
Case 1: ⌊xP/2⌋=⌊yP/2⌋=⌊zP/2⌋⌊xP/2⌋=⌊yP/2⌋=⌊zP/2⌋
Then xx, yy, and zz definitely form a triangle. Accounting for this case alone is sufficient for test cases 5 and 6.
Case 2: x,y,zx,y,z form a triangle but the condition ⌊xP/2⌋=⌊yP/2⌋=⌊zP/2⌋⌊xP/2⌋=⌊yP/2⌋=⌊zP/2⌋ is not satisfied. WLOG assume that ⌊xP/2⌋<⌊yP/2⌋=⌊zP/2⌋⌊xP/2⌋<⌊yP/2⌋=⌊zP/2⌋. Clearly y⊕z<Ky⊕z<K holds, so we only need to check that both x⊕y<Kx⊕y<K and x⊕z<Kx⊕z<K hold.
So for all t≥0t≥0 and each x∈[Pt,Pt+P/2)x∈[Pt,Pt+P/2), we must add ({y:y∈[Pt+P/2,Pt+P) and x⊕y<K}2)({y:y∈[Pt+P/2,Pt+P) and x⊕y<K}2) to the answer. This is what the recursive function add_to_answeradd_to_answer in my code below accounts for (read it for more details).
The number of times add_to_answeradd_to_answer is called and the overall running time are O(Nlog2K)O(Nlog2K). O(N⋅(log2K)2)O(N⋅(log2K)2) or O(N⋅(log2K)3)O(N⋅(log2K)3) solutions with reasonable constant factors should also receive full credit.
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9+7; // 998244353;
template<class T> bool ckmin(T& a, const T& b) {
return b < a ? a = b, 1 : 0; } // set a = min(a,b)
template<class T> bool ckmax(T& a, const T& b) {
return a < b ? a = b, 1 : 0; }
/**
* Description: modular arithmetic operations
* Source:
* KACTL
* https://codeforces.com/blog/entry/63903
* https://codeforces.com/contest/1261/submission/65632855 (tourist)
* https://codeforces.com/contest/1264/submission/66344993 (ksun)
* also see https://github.com/ecnerwala/cp-book/blob/master/src/modnum.hpp (ecnerwal)
* Verification:
* https://open.kattis.com/problems/modulararithmetic
*/
template<int MOD, int RT> struct mint {
static const int mod = MOD;
int v; explicit operator int() const { return v; } // explicit -> don't silently convert to int
mint() { v = 0; }
mint(long long _v) { v = int((-MOD < _v && _v < MOD) ? _v : _v % MOD);
if (v < 0) v += MOD; }
friend bool operator==(const mint& a, const mint& b) {
return a.v == b.v; }
friend bool operator!=(const mint& a, const mint& b) {
return !(a == b); }
friend bool operator<(const mint& a, const mint& b) {
return a.v < b.v; }
friend string to_string(mint a) { return to_string(a.v); }
mint& operator+=(const mint& m) {
if ((v += m.v) >= MOD) v -= MOD;
return *this; }
mint& operator-=(const mint& m) {
if ((v -= m.v) < 0) v += MOD;
return *this; }
mint& operator*=(const mint& m) {
v = int((long long)v*m.v%MOD); return *this; }
mint& operator/=(const mint& m) { return (*this) *= inv(m); }
friend mint pow(mint a, long long p) {
mint ans = 1; assert(p >= 0);
for (; p; p /= 2, a *= a) if (p&1) ans *= a;
return ans; }
friend mint inv(const mint& a) { assert(a.v != 0);
return pow(a,MOD-2); }
mint operator-() const { return mint(-v); }
mint& operator++() { return *this += 1; }
mint& operator--() { return *this -= 1; }
friend mint operator+(mint a, const mint& b) { return a += b; }
friend mint operator-(mint a, const mint& b) { return a -= b; }
friend mint operator*(mint a, const mint& b) { return a *= b; }
friend mint operator/(mint a, const mint& b) { return a /= b; }
};
vector<vector<mint<MOD,5> > > scmb; // small combinations, 5 is primitive root for both common mods
void genComb(int SZ) {
scmb.assign(SZ,vector<mint<MOD,5> > (SZ)); scmb[0][0] = 1;
for(int i=1; i<SZ; ++i) for(int j = 0; j<i+1; ++j)
scmb[i][j] = scmb[i-1][j]+(j?scmb[i-1][j-1]:0);
}
int N,K,P = 1;
mint<MOD,5> i2 = mint<MOD,5> (1)/2, i6 = mint<MOD,5> (1)/6;
mint<MOD,5> c2(mint<MOD,5> x) { return mint<MOD,5> ((long long)x.v*(x.v-1)/2); }
mint<MOD,5> c3(mint<MOD,5> x) { return x*(x-1)*(x-2)*i6; }
mint<MOD,5> ans = 0;
int total_length(const vector<pair<int,int> >& v) { // total length of intervals
int len = 0; for (auto& t: v) len += t.second-t.first+1;
return len;
}
// a and b are sets of intervals in [0,block)
// for each x in a, we want to add the following quantity to the answer:
// \binom{cur+size({y | y in b and x^y < (block-1)&K})}{2}
void add_to_answer(const vector<pair<int,int> >& a, const vector<pair<int,int> >& b, int block, mint<MOD,5> cur) {
// base cases
if (!int((a).size())) return;
if (!int((b).size())) {
ans += total_length(a)*c2(cur);
return;
}
vector<pair<int,int> > des{{0,block-1}};
if (b == des) { // b = [0,block)
cur += (block-1)&K;
ans += total_length(a)*c2(cur);
return;
}
// otherwise recurse
vector<pair<int,int> > A[2], B[2];
auto ad = [&](vector<pair<int,int> >& v, pair<int, int> p) {
ckmax(p.first,0), ckmin(p.second,block/2-1);
if (p.first > p.second) return;
v.push_back(p);
};
for (auto& t: a) ad(A[0],t), ad(A[1],{t.first-block/2,t.second-block/2});
for (auto& t: b) ad(B[0],t), ad(B[1],{t.first-block/2,t.second-block/2});
if (K&(block/2)) {
for(int i=0; i<2; ++i) add_to_answer(A[i],B[i^1],block/2,cur+total_length(B[i]));
} else {
for(int i=0; i<2; ++i) add_to_answer(A[i],B[i],block/2,cur);
}
}
void deal(vector<pair<int,int> > v) { // [0,P)
int P2 = P/2;
vector<pair<int,int> > tot[2];
for (auto& t: v) {
if (t.first/P2 < t.second/P2) {
tot[0].push_back({t.first,P2-1});
tot[1].push_back({0,t.second-P2});
} else {
tot[t.first/P2].push_back({t.first%P2,t.second%P2});
}
}
for(int i=0; i<2; ++i) {
ans += c3(total_length(tot[i])); // case 1
add_to_answer(tot[i],tot[i^1],P2,0); // case 2
}
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> N >> K;
++ K; while (P <= K) P *= 2; // P > K
K = K-P/2; assert(0 <= K && K < P/2);
mint<MOD,5> sing = P*c2(K)+2*c3(P/2); // answer for interval covering [0,P)
map<int,vector<pair<int,int> > > todo;
for(int i=0; i<N; ++i) {
int L,R; cin >> L >> R;
int LL = L/P, RR = R/P;
if (LL != RR) {
ans += (RR-LL-1)*sing;
todo[LL].push_back({L%P,P-1});
todo[RR].push_back({0,R%P});
} else {
todo[LL].push_back({L%P,R%P});
}
}
for (auto& t: todo) deal(t.second);
cout << to_string(ans) << endl;
}
A similar approach (with the same time complexity) involves writing a modified bitwise trie that supports the following operations on an array a[⋅]a[⋅] (where all additions come before all queries, although it is possible to support interleaved additions and queries).
[/hide]

© 2025. All Rights Reserved. 沪ICP备2023009024号-1