Codeforces Round #835 (Div. 4) 解题报告

提前开香槟,应该无人赛中看见?。

A. Medium Number

求三个数的和减去最大最小值即可

B. Atilla’s Favorite Problem

求给定字符串中的最大字符减去a加一即可

C. Advantage

首先排序判断最大值是否唯一,不唯一就全部减最大值即为答案,否则除最大值减去次大值外其余均减去最大值

D. Challenging Valleys

容易发现如果存在$a_i < a_{i+1}$,那么$\forall i \leqslant j$,均有$a_j \leqslant a_{j+1}$,否则就为No

Code:

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

ll tt,n,a[(int)2e5+9];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>tt;
    f(sb,1,tt){
        cin>>n;
        f(i,1,n)cin>>a[i];
        int st=0;
        bool ok=true;
        f(i,2,n){
            if(a[i]>a[i-1]){st=i;break;}
        }
        if(st){
            for(int i=st;i<=n;++i){
                if(a[i]<a[i-1]){
                    ok=false;
                    break;
                }
            }
        }
        cout<<(ok?"YES\n":"NO\n");
    }
    return 0;
}

E. Binary Inversions

不考虑改变的话,答案就是每个$0$前面的$1$的个数的和。

求改变就可以遍历每个$a_i$,计算改变该处值后的答案取max即可。

Code:

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

ll tt,n,a[(int)2e5+9],b[(int)2e5+9];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>tt;
    f(sb,1,tt){
        cin>>n;
        f(i,1,n)cin>>a[i],b[i]=b[i-1]+a[i];
        ll ans=0;
        f(i,1,n)if(a[i]==0)ans+=b[i-1];
        ll tmp=ans;
        f(i,1,n){
            if(a[i]){
                ans=max(ans,tmp+b[i-1]-((n-i)-(b[n]-b[i])));
            }else ans=max(ans,tmp+((n-i)-(b[n]-b[i]))-b[i-1]);
        }
        cout<<ans<<"\n";
    }
    return 0;
}

F. Quests

首先排序求前缀和,然后考虑一些特殊情况: Infinity的情况就是前$d$个任务的金币已经够了,Impossible就是连续$d$天都取金币最多的任务也不能完成的情况。

接下来就是求$k$了,二分即可。

Code:

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

ll tt,n,c,d,a[(int)2e5+9],s[(int)2e5+9];

ll solve(int l,int r){
    while(l<r){
        ll mid=(l+r+1)>>1;
        ll res=s[min(mid+1,n)]*(d/(mid+1))+s[min(d%(mid+1),n)];
        if(c<=res)l=mid;
        else r=mid-1;
    }
    return l;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>tt;
    f(sb,1,tt){
        cin>>n>>c>>d;
        f(i,1,n)cin>>a[i];
        sort(a+1,a+1+n,[](ll x,ll y){return x>y;});
        f(i,1,n)s[i]=s[i-1]+a[i];
        if(s[min(d,n)]>=c){
            cout<<"Infinity\n";
        }else if(a[1]*d<c){
            cout<<"Impossible\n";
        }else cout<<solve(0,d-2)<<"\n";
    }
    return 0;
}

G. SlavicG’s Favorite Problem

容易发现是不会走回头路的,所以我们从点$a$开始dfs,记录到每个点时$x$的值,然后判断是否可以直接到点$b$,是直接返回true即可,dfs时注意不要过点$b$。

接下来就可以从点$b$开始dfs,并判断从$a$开始dfs的点中是否存在相同值的点,注意要删除经过的路径上的点的贡献,存在便返回true

Code:

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

ll tt,n,a,b,dp[(int)1e5+9],f[(int)1e5+9];
int tot,hd[(int)1e5+9];
bitset<(int)1e5+9> vis;
struct Edge{
	int to,nxt,v;
}e[(int)4e5+9];
void add(int u,int v,int w){
	e[++tot]={u,hd[v],w},hd[v]=tot;
	e[++tot]={v,hd[u],w},hd[u]=tot;
}

void dfs(int u,int val){
	if(vis[u])return ;
	vis[u]=1;
	dp[u]=val;
	if(u==b)return ;
	for(int eg=hd[u];eg;eg=e[eg].nxt){
		dfs(e[eg].to,e[eg].v^val);
	}
}
map<int,int> exi;
bool dfs2(int u,int val){
	if(vis[u])return 0;
	vis[u]=1;
	bool ok=false;
	f[u]=val;
	//cerr<<u<<"::"<<val<<"\n";
	if(exi.count(f[u])&&u!=b)if(exi[f[u]])return true;
	//cerr<<u<<"__\n";
	//if(u==a)return 0;
	for(int eg=hd[u];eg;eg=e[eg].nxt){
		if(~dp[e[eg].to]&&e[eg].to!=b)exi[dp[e[eg].to]]-=1;
		ok|=dfs2(e[eg].to,e[eg].v^val);
		if(~dp[e[eg].to]&&e[eg].to!=b)exi[dp[e[eg].to]]+=1;
	}
	return ok;
}

bool solve(){
	exi.clear();
	cin>>n>>a>>b;
	tot=1,vis.reset();
	f(i,1,n)hd[i]=0,dp[i]=-1,f[i]=-1;
	for(int i=2,x,y,z;i<=n;++i){
		cin>>x>>y>>z;
		add(x,y,z);
	}
	dfs(a,0);
	vis.reset();
	if(dp[b]==0)return true;
	f(i,1,n)if(~dp[i]&&i!=b)exi[dp[i]]+=1;
	//f(i,1,n)cout<<dp[i]<<" \n"[i==n];
	return dfs2(b,0);
	return false;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>tt;
    f(sb,1,tt)cout<<(solve()?"YES\n":"NO\n");
    return 0;
}
 
上一篇
下一篇