比赛链接:https://codeforces.com/contest/2085
A.Serval and String Theory
思路:我看了快4分钟才明白题意,显然字符串的字符全相等或者k==0时,字符串不符合题意即无解,否则就是对的
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)
{ll ans = 1;x %= mod;while (y){if (y & 1){ans = ans * x % mod;}x = x * x % mod;y >>= 1;}return ans;
}
ll gcd(ll x, ll y)
{if (y == 0)return x;elsereturn gcd(y, x % y);
}
inline ll read()
{register ll x = 0, f = 1;char c = getchar();while (c < '0' || c>'9'){if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速c = getchar();}return x * f;
}
void fio()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
}
struct s
{ll l,r;friend bool operator<(const s &a, const s& b){return a.l<b.l;};
};
int main()
{fio();ll t;cin >> t;while (t--){ll n,k;cin>>n>>k;string f;cin>>f;ll cnt=0;for(ll i=0;i<n;i++){cnt+=(f[i]==f[0]);}ll pd=0;for(ll i=0;i<n;i++){if(f[i]<f[n-i-1]){pd=1;break;}else if(f[i]>f[n-i-1]){pd=2;break;}}if(cnt==n||(k==0&&(pd==2||pd==0))){cout<<"NO"<<endl;}else cout<<"YES"<<endl;}return 0;
}
B.Serval and Final MEX
思路:全0就分成一半一半,然后统一合并。全为大于0的数字就直接全合成就好了。有0和有大于0的数字,我是这样想的。
如果最后两位有至少一个0出现,那么他们两个合并下,然后去遍历前面的数(n-2个数)看下前面的数否全为大于0的数,如果前面全大于0则不合成,最后大合成就好
否则,最后两个数不合成,前面n-2 个数合成下,最后再大合成即可
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)
{ll ans = 1;x %= mod;while (y){if (y & 1){ans = ans * x % mod;}x = x * x % mod;y >>= 1;}return ans;
}
ll gcd(ll x, ll y)
{if (y == 0)return x;elsereturn gcd(y, x % y);
}
inline ll read()
{register ll x = 0, f = 1;char c = getchar();while (c < '0' || c>'9'){if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速c = getchar();}return x * f;
}
void fio()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
}
struct s
{ll l,r;friend bool operator<(const s &a, const s& b){return a.l<b.l;};
};
int main()
{fio();ll t;cin >> t;while (t--){ll n;cin>>n;vector<ll>a(n+5);ll cnt=0;ll wz;for(ll i=1;i<=n;i++){cin>>a[i];cnt+=(a[i]==0);}if(cnt==0){cout<<1<<endl;cout<<1<<" "<<n<<endl;}else if(cnt!=n){if(a[n-1]==0||a[n]==0){ll pd=0;ll f=0;for(ll i=1;i<=n-2;i++){if(a[i]>0)f++;}if(f!=n-2){cout<<3<<endl;cout<<n-1<<" "<<n<<endl;cout<<1<<" "<<n-2<<endl;cout<<1<<" "<<2<<endl;}else {cout<<2<<endl;cout<<n-1<<" "<<n<<endl;cout<<1<<" "<<n-1<<endl;}}else{cout<<2<<endl;cout<<1<<" "<<n-2<<endl;cout<<1<<" "<<3<<endl;}}else {cout<<3<<endl;cout<<n-1<<" "<<n<<endl;cout<<1<<" "<<n-2<<endl;cout<<1<<" "<<2<<endl;}}return 0;
}
C.Serval and The Formula
思路:其实仔细写写发现就是去尽量消除x和y在某个二进制位同为1的情况,发现能消除的方法就是找更低的二进制位为(0和1)的情况,然后不断进位即可。写的时间复杂度就60*60吧,其实还有O(1)办法,应该是这个吧,(1ll<<30)-max(x,y).
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)
{ll ans = 1;x %= mod;while (y){if (y & 1){ans = ans * x % mod;}x = x * x % mod;y >>= 1;}return ans;
}
ll gcd(ll x, ll y)
{if (y == 0)return x;elsereturn gcd(y, x % y);
}
inline ll read()
{register ll x = 0, f = 1;char c = getchar();while (c < '0' || c>'9'){if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速c = getchar();}return x * f;
}
void fio()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
}
struct s
{ll l,r;friend bool operator<(const s &a, const s& b){return a.l<b.l;};
};
int main()
{fio();ll t;cin >> t;while (t--){ll x,y;cin>>x>>y;//cout<<ll k=0;ll ok=0;for(ll i=0;i<=60;i++){ll z=(1ll<<i);if((x&z)&&(y&z)){while((x&z)&&(y&z)){ ll pd=0;for(ll j=i-1;j>=0;j--){ll o=1ll<<j;if(((x&o)==0&&(y&o)>0)||((y&o)==0&&(x&o)>0)){pd=1;x+=o;y+=o;k+=o;break;}}if(pd==0)break;}if(((x&z)&&(y&z))&&i>=55){ok=1;break;}else if((x&z)&&(y&z)){x+=z;y+=z;k+=z;}}}if(ok||k>1e18)cout<<-1<<endl;else cout<<k<<endl;}return 0;
}
//100100100100100100100
// 10010010010010010100
D.Serval and Kaitenzushi Buffet
思路:反悔贪心,每次看吃的时间够不够,够得话就拿走吃的,否则就看要不要最小的换下即可
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)
{ll ans = 1;x %= mod;while (y){if (y & 1){ans = ans * x % mod;}x = x * x % mod;y >>= 1;}return ans;
}
ll gcd(ll x, ll y)
{if (y == 0)return x;elsereturn gcd(y, x % y);
}
inline ll read()
{register ll x = 0, f = 1;char c = getchar();while (c < '0' || c>'9'){if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速c = getchar();}return x * f;
}
void fio()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
}
struct s
{ll v, id;friend bool operator<(const s& a, const s& b){return a.v > b.v;};
};
int main()
{fio();ll t;cin >> t;while (t--){ll n, k;cin >> n >> k;vector<ll>a(n + 5);for (ll i = 1; i <= n; i++){cin >> a[i];}ll cnt = k;priority_queue<s>f;ll ans = 0;ll sum = 0;for (ll i = n - k; i >= 1; i--){if (cnt >= k){f.push({ a[i],i });sum += a[i];cnt -= k;}else{ll v = f.top().v;if (v >= a[i]){cnt++;continue;}else{sum -= v;f.pop();f.push({ a[i],i });cnt++;sum += a[i];}}ans = max(ans, sum);}cout << ans << endl;}return 0;
}
//100100100100100100100
// 10010010010010010100
E.Serval and Modulo
思路:赛后补的。看了jangly的代码。对于正确的{a[i],b[i]}对,其实(a[i]-b[i])一定是k的倍数,除了a数组等于b数组情况。
所以我们可以把所有(a[i]-b[i])加起来即可,然后分解因数去检测下就可以做出来,实际因数不多,其实不等于nsqrt(n)logn,时间复杂度远比这个小,因为因数其实很少,不是因数的时间复杂度上算加法
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)
{ll ans = 1;x %= mod;while (y){if (y & 1){ans = ans * x % mod;}x = x * x % mod;y >>= 1;}return ans;
}
ll gcd(ll x, ll y)
{if (y == 0)return x;elsereturn gcd(y, x % y);
}
inline ll read()
{register ll x = 0, f = 1;char c = getchar();while (c < '0' || c>'9'){if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速c = getchar();}return x * f;
}
void fio()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
}
struct s
{ll v, id;friend bool operator<(const s& a, const s& b){return a.v > b.v;};
};
int main()
{fio();ll t;cin >> t;while (t--){ll n;cin>>n;//如果有答案,那么差值一定包含这个答案的倍数vector<ll>a(n+5,0),b(n+5,0);for(ll i=1;i<=n;i++)cin>>a[i];for(ll i=1;i<=n;i++)cin>>b[i];sort(a.begin()+1,a.begin()+1+n);sort(b.begin()+1,b.begin()+1+n);ll f=0;for(ll i=1;i<=n;i++){f+=a[i]-b[i];}if(a==b){cout<<(ll)1e9<<endl;continue;}if(f<=0){cout<<-1<<endl;continue;}function<ll(ll)>ck=[&](ll x){if(x>(ll)1e9)return 0;vector<ll>f(n+5,0);f=a;for(ll i=1;i<=n;i++){f[i]%=x;}sort(f.begin()+1,f.begin()+1+n);if(f==b)return 1;else return 0;};ll ans=-1;for(ll i=1;i*i<=f;i++){if(f%i==0){if(ck(i)){ans=i;break;}if(ck(f/i)){ans=f/i;break;}}}cout<<ans<<endl;}
}
//100100100100100100100
// 10010010010010010100