H-gcd xor
/*
题意:给你一个数N, 问你gcd(a, b) = a xor b的对数?
分析:我们枚举c(gcd(a, b) = c) 和 a, 然后算出b判断即可。
*/
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 30000000 + 10;
typedef long long LL;
LL N;
LL f[maxn];
int main() {
int T; scanf("%d", &T);
int kase = 0;
N = 30000000;
LL res = 0;
for(LL c=1; c<=N; c++)
for(LL a=c+c; a<=N; a+=c) {
LL b = a - c;
if((a^b) == c) {
f[a]++;
}
}
for(LL i=1; i<=N; i++) {
f[i] += f[i-1];
}
while(T--) {
cin >> N;
printf("Case %d: %lld\n", ++kase, f[N]);
}
return 0;
}
/*
题意:给你N个区间l, r, 以及m个点pti, 让你求距离pti最合适的区间所对应的值,定义pti对于一个区间li, ri的合适值为:1如果这个点在li, ri外面,那么合适
值为0, 如果在内的话那么就是min(pti-li, ri-pti).
分析:我们找到区间的中点,首先考虑左端点对答案的贡献, 将li, midi, pti放进数组里面, 遇到li将其放入set, 遇到midi删掉对应的li, 遇到pti,则查询set里面的
最小值。 对于ri做同样的处理即可。
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
using namespace std;
const int maxn = 100000 + 100;
int N, M;
int l[maxn], r[maxn];
struct Node{
int k1, flog, k2; //flog -1表示端点 0表示查询 1表示mid删除
};
vector<Node> arr1, arr2;
set<pair<int, int> >st;
int ans[maxn];
bool cmp1(const Node&a, const Node&b) {
if(a.k1 == b.k1) return a.flog < b.flog;
else return a.k1 < b.k1;
}
bool cmp2(const Node&a, const Node&b) {
if(a.k1 == b.k1) return a.flog < b.flog;
else return a.k1 > b.k1;
}
int main() {
int T; scanf("%d", &T);
int kase = 0;
while(T--) {
scanf("%d%d", &N, &M);
arr1.clear(); arr2.clear();
for(int i=1; i<=N; i++) {
int t1, t2; scanf("%d%d", &t1, &t2);
l[i] = t1; r[i] = t2;
int mid = (t1 + t2)/2; //flog -1表示端点 0表示查询 1表示mid删除
if((t1+t2)%2==0) {
arr1.push_back((Node){t1, -1, i});
arr1.push_back((Node){mid, 1, i});
arr2.push_back((Node){t2, -1, i});
arr2.push_back((Node){mid, 1, i});
}else{
arr1.push_back((Node){t1, -1, i});
arr1.push_back((Node){mid, 1, i});
arr2.push_back((Node){t2, -1, i});
arr2.push_back((Node){mid+1, 1, i});
}
}
for(int i=1; i<=M; i++) {
int t; scanf("%d", &t);
arr1.push_back((Node){t, 0, i});
arr2.push_back((Node){t, 0, i});
}
sort(arr1.begin(), arr1.end(), cmp1);
memset(ans, 0, sizeof(ans));
st.clear(); //flog -1表示端点 0表示查询 1表示mid删除
for(int i=0; i<arr1.size(); i++) {
if(arr1[i].flog == -1) {
st.insert(make_pair(arr1[i].k1, arr1[i].k2));
}else if(arr1[i].flog == 1) {
int idx = arr1[i].k2;
st.erase(make_pair(l[idx], idx));
}else{
int aidx = arr1[i].k2, t = arr1[i].k1;
if(!st.empty()) {
pair<int, int> tp = *st.begin();
ans[aidx] = max(ans[aidx], t - tp.first);
}
}
}
st.clear(); //flog -1表示端点 0表示查询 1表示mid删除
sort(arr2.begin(), arr2.end(), cmp2);
for(int i=0; i<arr2.size(); i++) {
if(arr2[i].flog == -1) {
st.insert(make_pair(arr2[i].k1, arr2[i].k2));
}else if(arr2[i].flog == 1) {
int idx = arr2[i].k2;
st.erase(make_pair(r[idx], idx));
}else{
int aidx = arr2[i].k2, t = arr2[i].k1;
if(!st.empty()) {
pair<int, int> tp = *(--st.end());
ans[aidx] = max(ans[aidx], tp.first-t);
}
}
}
printf("Case %d:\n", ++kase);
for(int i=1; i<=M; i++)
printf("%d\n", ans[i]);
}
return 0;
}