Codeforces Round 1047 (Div. 3)(A~F|G待补)
这次比赛还是比较好想的,但是被C卡了(把C作为了最后一题做)
比赛链接:https://codeforces.com/contest/2137
A.Collatz Conjecture
思路:一直乘2,最多倍增20次,远远不到INT_MAX
#pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")
#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"// ???????
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
// const ll N = 5e5 + 10;
// const ull p=1145161651561;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans * x % mod;
}
x = x * x % mod;
y >>= 1;
}
return ans % mod;
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
const ll N = 3e5 + 5;
struct s {
ll l,r,id;
friend bool operator<(const s& a, const s& b) {
if(a.l!=b.l)return a.l<b.l;
else return a.r<b.r;
// return a.v < b.v;
}
};
ll e[4] = { 0,1,0,-1 };
ll d[4] = { 1,0,-1,0 };
void solve() {
ll x,k;
cin>>x>>k;
swap(x,k);
for(ll i=1;i<=k;i++){
x*=2;
}
cout<<x<<endl;
}
int main() {
fio();
ll t = 1;
cin>>t;
while (t--)solve();
return 0;
}
B.Fun Permutation
思路:把所有数补成对应位置之和为n+1就行了
#pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")
#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"// ???????
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
// const ll N = 5e5 + 10;
// const ull p=1145161651561;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans * x % mod;
}
x = x * x % mod;
y >>= 1;
}
return ans % mod;
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
const ll N = 3e5 + 5;
struct s {
ll l,r,id;
friend bool operator<(const s& a, const s& b) {
if(a.l!=b.l)return a.l<b.l;
else return a.r<b.r;
// return a.v < b.v;
}
};
ll e[4] = { 0,1,0,-1 };
ll d[4] = { 1,0,-1,0 };
void solve() {
ll n;
cin>>n;
vector<ll>a(n+2);
for(ll i=1;i<=n;i++)cin>>a[i];
for(ll i=1;i<=n;i++)cout<<n-a[i]+1<<" ";
cout<<endl;
}
int main() {
fio();
ll t = 1;
cin>>t;
while (t--)solve();
return 0;
}
C.Maximum Even Sum
思路:分类讨论下。
\[首先基本思想:设 b = e \cdot f, \\
如果 a \cdot k + \frac{b}{k} 要变大,那么就说明 \frac{b}{k} < a, \\
且这个 \frac{b}{k} 越小就越好。\\
\]
\[如果 a 为偶数,b 为偶数,那么只要 \frac{b}{k} 不为奇数, \\
那么都是可能答案,根据基本思想,可以得出 \frac{b}{2} \cdot a + 2
\]
\[如果a为奇数,b为奇数,那么可以得出答案为a \cdot b +1
\]
\[如果a为奇数,b为偶数,那么必须从b中拿出一个偶数乘以a,所以\frac{b}{2} % 2!=0,则无解
,否则答案为\frac{b}{2} \cdot a+2
\]
\[如果a为偶数,b为奇数,则无解
\]
#pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")
#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"// ???????
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
// const ll N = 5e5 + 10;
// const ull p=1145161651561;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans * x % mod;
}
x = x * x % mod;
y >>= 1;
}
return ans % mod;
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
const ll N = 3e5 + 5;
struct s {
ll l,r,id;
friend bool operator<(const s& a, const s& b) {
if(a.l!=b.l)return a.l<b.l;
else return a.r<b.r;
// return a.v < b.v;
}
};
ll e[4] = { 0,1,0,-1 };
ll d[4] = { 1,0,-1,0 };
void solve() {
ll a,b;
cin>>a>>b;
if(((a&1)^(b&1))!=0){
if(b%2==1)cout<<-1<<endl;
else{
if((b/2)%2==1)cout<<-1<<endl;
else{
cout<<a*(b/2)+2<<endl;
}
}
}
else {
if(a%2==0){
// if((b/2)%2==1)cout<<a+b<<endl;
cout<<a*(b/2)+2<<endl;
}
else {
cout<<a*b+1<<endl;
}
}
}
int main() {
fio();
ll t = 1;
cin>>t;
while (t--)solve();
return 0;
}
D.Replace with Occurrences
思路:对于给出数组中一个值x来看,如果x出现x次,那么肯定是可以的,但是出现x的倍数也对,因为x个1和x个2,x出现了2*x次。所以只要去检验每个数的出现次数%自己是否等于0。如果都是,则根据给出数字x的位置,x个,x个赋值即可
#pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")
#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"// ???????
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
// const ll N = 5e5 + 10;
// const ull p=1145161651561;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans * x % mod;
}
x = x * x % mod;
y >>= 1;
}
return ans % mod;
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
const ll N = 3e5 + 5;
struct s {
ll l,r,id;
friend bool operator<(const s& a, const s& b) {
if(a.l!=b.l)return a.l<b.l;
else return a.r<b.r;
// return a.v < b.v;
}
};
ll e[4] = { 0,1,0,-1 };
ll d[4] = { 1,0,-1,0 };
void solve() {
ll n;
cin>>n;
vector<ll>a(n+2),b(n+2,0);
for(ll i=1;i<=n;i++){
cin>>a[i];
b[a[i]]++;
}
ll cc=0;
set<ll>u;
vector<vector<ll>>pos(n+2);
for(ll i=1;i<=n;i++){
if(b[a[i]]%a[i]!=0)cc++;
pos[a[i]].push_back(i);
u.insert(a[i]);
}
if(cc>0)cout<<-1<<endl;
else {
ll l=1;
for(auto j:u){
ll cnt=0;
for(auto k:pos[j]){
cnt++;
a[k]=l;
if(cnt%j==0)l++;
}
}
for(ll i=1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
}
}
int main() {
fio();
ll t = 1;
cin>>t;
while (t--)solve();
return 0;
}
E.Mexification
思路:不妨设0-x在数组中只出现了一次,那么他们总是不会变化的,会变化的只会是出现了重复数,或者突然断开了如0~x,x+5.中的x+5,我们可以枚举下,发现其值变化状态很快收敛于两种。这里直接让它跑了max(k,60),最后看k-max(k,60)的奇偶性即可,如果奇性再来一次变化即可
#pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")
#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"// ???????
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
// const ll N = 5e5 + 10;
// const ull p=1145161651561;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans * x % mod;
}
x = x * x % mod;
y >>= 1;
}
return ans % mod;
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
const ll N = 3e5 + 5;
struct s {
ll l,r,id;
friend bool operator<(const s& a, const s& b) {
if(a.l!=b.l)return a.l<b.l;
else return a.r<b.r;
// return a.v < b.v;
}
};
ll e[4] = { 0,1,0,-1 };
ll d[4] = { 1,0,-1,0 };
void solve() {
ll n,k;
cin>>n>>k;
vector<ll>a(n+2),b(n+2);
for(ll i=1;i<=n;i++){
cin>>a[i];
}
sort(a.begin()+1,a.begin()+1+n);
for(ll i=1;i<=min(k,60ll);i++){
b=a;
vector<ll>vis(n+5,0);
ll l=0;
for(ll j=1;j<=n;j++){
vis[b[j]]++;
if(b[j]==l)l++;
}
for(ll j=1;j<=n;j++){
if(b[j]<=l){
if(vis[b[j]]==1)continue;
else b[j]=l;
}
else {
b[j]=l;
}
}
a=b;
}
ll ans=0;
k-=min(k,60ll);
if(k%2==0){
for(ll j=1;j<=n;j++){
ans+=b[j];
}
}
else {
vector<ll>vis(n+5,0);
ll l=0;
for(ll j=1;j<=n;j++){
vis[b[j]]++;
if(b[j]==l)l++;
}
for(ll j=1;j<=n;j++){
if(b[j]<=l){
if(vis[b[j]]==1)continue;
else b[j]=l;
}
else {
b[j]=l;
}
}
for(ll j=1;j<=n;j++){
ans+=b[j];
}
}
cout<<ans<<endl;
}
int main() {
fio();
ll t = 1;
cin>>t;
while (t--)solve();
return 0;
}
F.Prefix Maximum Invariance
思路:这里采用了线段树+贡献法
\[从左往右枚举i.
用线段树维护遍历完了的每个位置的对应值的最大位置(有点绕)
如果a[i]==b[i],那么这个位置能对的状态数为i*(n-i+1)
\]
\[否则可以取线段树维护中max(a[i],b[i])-2*n的最大值,注意1e18直接跳,否则答案就是pos*(n-i+1)
,最后把所有贡献加起来即可
\]
#pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")
#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"// ???????
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
// const ll N = 5e5 + 10;
// const ull p=1145161651561;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans * x % mod;
}
x = x * x % mod;
y >>= 1;
}
return ans % mod;
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
const ll N = 4e5 + 5;
struct tree {
ll v;
ll l, r;
}p[N << 2];
void build(ll i, ll l, ll r) {
p[i].l = l, p[i].r = r;
p[i].v = 0;
if (l == r)return;
build(i << 1, l, l + r >> 1);
build(i << 1 | 1, (l + r >> 1) + 1, r);
}
void update(ll i, ll tar, ll x) {//大
if (p[i].l == p[i].r) {
p[i].v = x;
return;
}
ll mid = p[i].l + p[i].r >> 1;
if (tar <= mid)update(i << 1, tar, x);
else update(i << 1 | 1, tar, x);
p[i].v = max(p[i << 1].v, p[i << 1 | 1].v);
}
ll query(ll i, ll l, ll r) {
ll ans = 0;
if (p[i].l == l && p[i].r == r) {
return p[i].v;
}
ll mid = p[i].l + p[i].r >> 1;
if (l <= mid)ans = max(ans, query(i << 1, l, min(mid, r)));
if (r >= mid + 1)ans = max(ans, query(i << 1 | 1, max(mid + 1, l), r));
return ans;
}
void solve() {
ll n;
cin >> n;
vector<ll>a(n + 2);
vector<ll>b(n + 2);
build(1, 1, 2 * n);
for (ll i = 1; i <= n; i++)cin >> a[i];
for (ll i = 1; i <= n; i++)cin >> b[i];
ll ans = 0;
for (ll i = 1; i <= n; i++) {
if (a[i] == b[i])ans += i * (n - i + 1);
else if(i>1){
ll cc = query(1, max(a[i], b[i]), 2 * n);
if (cc != 0) {
ans += cc * (n - i + 1);
}
}
update(1, a[i], i);
}
// if (a[1] == b[1])ans += n - 1;
cout << ans << endl;
}
int main() {
fio();
ll t = 1;
cin >> t;
while (t--)solve();
return 0;
}

浙公网安备 33010602011771号