【题解】CF1835 合集
CF1835A k-th equality
标签:可以改编+改进的题
\(B\)
我们考虑因为题目上说:
Each input file has at most \(5\) test cases which do not satisfy \(A,B,C \leq 3\).
不满足 \(A,B,C \leq 3\) 的数据最多只有 \(5\) 组
所以说,我们可以枚举所有的 \(A\) 位数,然后每次减去可能的 \(B\) 位数的个数即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int NN = 10;
int t,a,b,c;
ll k;
ll l[NN] = {0,1,10,100,1000,10000,100000,1000000};
ll r[NN] = {0,9,99,999,9999,99999,999999,9999999};
int main(){
scanf("%d",&t);
while(t--){
scanf("%d %d %d %lld",&a,&b,&c,&k);
if(c != max(a,b) && c != max(a,b)+1) {puts("-1");continue;}
ll ans = k;
for(ll i = l[a]; i <= r[a]; ++i){
ll lt = max(l[b],l[c] - i),rt = min(r[b],r[c] - i);
if(lt > rt) rt = lt - 1;
if(ans <= (rt - lt + 1)){
printf("%lld + %lld = %lld\n",i,lt + ans - 1,(i + lt + ans - 1));
ans = 0;
break;
}
ans -= (rt - lt + 1);
}
if(ans > 0) puts("-1");
}
}
CF1835C Twin Clusters
标签:思维题
\(C^+\)
你考虑我们对所有的正整数做前缀异或和操作,我们要做的就是找到四个数的异或和为 \(0\)(其中有两个数可以相同),然后我们就可以得到 \(2^{k+1} +1\) 个数。
我们将 \(4^k\) 拆成前 \(2^k\) 和后 \(2^k\),我们至少有 \(2^k+1\) 对数的异或和在二进制下前 \(k\) 位为 \(1\)。
根据鸽巢原理,这 \(2^k+1\) 对数一定可以凑出 \(4\) 个数的异或和为 \(0\)。
我们怎么求呢?
我们可以对于前 \(k\) 位开一个桶,后 \(k\) 位开一个 map
存数对(当然开桶也可以),然后对于每一对前 \(k\) 位异或和为零的数对,存到后 \(k\) 位的 map
中,如果当前位置已经有数对,就可以输出答案了。
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int NN = 1 << 20;
int t;
ll pre[NN];
ll tong[NN];
struct Pair{
int a,b;
};
int main(){
scanf("%d",&t);
while(t--){
int k;
scanf("%d",&k);
tong[0] = -1;
map<ll,Pair> mp;
for(ll i = 1,x; i <= (1 << (k+1)); ++i) scanf("%lld",&x),pre[i] = pre[i-1] ^ x,tong[i] = -1;
for(int i = 0; i <= (1 << (k+1)); ++i){
if(tong[pre[i] >> k] != -1){
if(mp.count(pre[i] ^ pre[tong[pre[i] >> k]])){
Pair x = mp[pre[i] ^ pre[tong[pre[i] >> k]]], y = {i,tong[pre[i] >> k]};
int w[4] = {x.a,x.b,y.a,y.b};
sort(w,w+4);
printf("%d %d %d %d\n",w[0]+1,w[1],w[2]+1,w[3]);
break;
}
else mp[pre[i] ^ pre[tong[pre[i] >> k]]] = {i,tong[pre[i] >> k]};
}
tong[pre[i] >> k] = i;
}
}
}
本文来自博客园,作者:ricky_lin,转载请注明原文链接:https://www.cnblogs.com/rickylin/p/CF1835.html