A.小苯的数字染色
易得由 ,
无法表示的数字有且仅有
。因此除了
之外的所有数字都可以。
时间复杂度 。
void solve(){
puts(read()>=2?"YES":"NO");
}
B.小苯的数组重排
赛时的数据疑似 ,攻击出题人后现在应该已经改成
了
原式显然可以化成 。
因此只需让 为最小的两个数字就行了。
时间复杂度 。
void solve(){
ll n = read();
vector<ll> a(n);
for(ll i=0;i<n;i++) a[i] = read();
sort(all(a));
ll ans = a[0] + a[1] + accumulate(a.begin()+2, a.end(), 0ll) * 2;
print(ans);
}
C.小苯的麦克斯
对于包含最大值的一个长度为 的子数组,不难发现往其中添加数字是不优的(会使答案减小或不变)。
因此只需检查最大值和周围元素组成的字数组即可。
时间复杂度 。
ll mex(ll a, ll b){
if(a > b) swap(a, b);
ll v = 0;
if(a == v) v++;
if(b == v) v++;
return v;
}
void solve(){
ll n = read();
vector<ll> a(n);
for(ll i=0;i<n;i++) a[i] = read();
ll mx = *max_element(all(a));
ll mxa = -INF;
for(ll i=0;i<n;i++){
if(a[i] == mx){
if(i){
mxa = max(mxa, mx - mex(mx, a[i-1]));
}
if(i < n-1){
mxa = max(mxa, mx - mex(mx, a[i+1]));
}
}
}
print(mxa);
}
D.小苯的平衡序列
遍历每个数,计算剩下的数字的中位数,把原式拆成两部分计算即可。
可以用 或者双堆实现。
时间复杂度 。
class DS{
public:
ll t1,t2;
DS(){
t1 = t2 = 0;
}
multiset<ll> q1,q2;
void clr(){
q1.clear();
q2.clear();
t1=t2=0;
}
void remake(){
while(q1.size()>q2.size()) q2.insert(*q1.rbegin()),t1-=*q1.rbegin(),t2+=*q1.rbegin(),q1.erase(--q1.end());
while(q1.size()<q2.size()) q1.insert(*q2.begin()),t1+=*q2.begin(),t2-=*q2.begin(),q2.erase(q2.begin());
}
void add(ll x){
q1.insert(x);t1+=x;
remake();
}
void del(ll x){
if(q1.find(x)!=q1.end()) q1.erase(q1.lower_bound(x)),t1-=x;
else q2.erase(q2.lower_bound(x)),t2-=x;
remake();
}
ll qry(){
if(q1.empty()) return 0ll;
return ll(q1.size())**q1.rbegin()-t1+t2-ll(q2.size())**q1.rbegin();
}
};
void solve(){
ll n = read();
DS ds;
vector<ll> a(n+1);
for(ll i=1;i<=n;i++){
a[i] = read();
ds.add(a[i]);
}
ll mi = INF;
for(ll i=1;i<=n;i++){
ds.del(a[i]);
mi = min(mi, ds.qry());
ds.add(a[i]);
}
print(mi);
}
E.小苯的数字变换
手玩一下可得 。
特例是 时
。
可以使用前缀和去枚举每个区间(前缀和对 取模)。
注意要处理区间是全 的情况,因此统计每个前缀和出现几次时,先加到
上,遇到非
数字再加回
中。
void solve(){
string s;cin>>s;
ll n = s.size();
s = " " + s;
vector<ll> pre(s.size());
vector<ll> cnt(10);
cnt[0] ++;
ll ans = 0;
vector<vector<ll>> pos(10);
vector<ll> temp(10);
for(ll i=1;i<=n;i++){
if (s[i] != '0') {
for (ll j = 0 ; j <= 9; j++) {
cnt[j] += temp[j];
temp[j] = 0;
}
}
pre[i] = (pre[i-1] + s[i]-'0')%9;
for(ll j=0;j<=9;j++) {
ll t = (pre[i] - j+18-1)%9+1;
ans += t * cnt[j];
}
temp[pre[i]]++;
}
cout<<ans<<'\n';
}
F.小苯的序列合并
考虑只有三个 或
的情况。
可以发现有一个 和两个
的时候,所有数字异或起来答案会变大。
其余情况答案不变。
因此当数组中元素大于 个时,我们一定能选出三个数字异或后答案不会减小,即最后会剩下一个或者两个数字。
因此我们只需要遍历每个分割点统计最大答案即可。
void solve(){
ll n = read();
vector<ll> a(n+1), pre(n+2), surf(n+2);
for(ll i=1;i<=n;i++){
a[i] = read();
pre[i] = pre[i-1] ^ a[i];
}
for(ll i=n;i>=1;i--){
surf[i] = surf[i+1] ^ a[i];
}
surf[n+1] = (1ll<<60)-1;
ll ans = 0;
for(ll i=1;i<=n;i++){
ans = max(ans, pre[i]&surf[i+1]);
}
print(ans);
}
火车头参考
// FZANOTFOUND
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define sep "======"
#define fastio ios::sync_with_stdio(false);cin.tie(0);
#define all(a) a.begin(), a.end()
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<long long,long long> PLL;
typedef tuple<ll,ll,ll> TLLL;
const ll INF = (ll)2e18+9;
//const ll MOD = 1000000007;
const ll MOD = 998244353;
const ld PI = 3.14159265358979323;
//io functions
inline void rd(ll &x){x=0;short f=1;char c=getchar();while((c<'0'||c>'9')&&c!='-') c=getchar();if(c=='-') f=-1,c=getchar();while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();x*=f;}
inline ll read(){ll x=0;short f=1;char c=getchar();while((c<'0'||c>'9')&&c!='-') c=getchar();if(c=='-') f=-1,c=getchar();while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();x*=f;return x;}
inline void pt(ll x){if(x<0) putchar('-'),x=-x;if(x>9) pt(x/10);putchar(x%10+'0');}
inline void print(ll x){pt(x), puts("");}
inline void print(PLL x){pt(x.fi), putchar(' '), pt(x.se), putchar('\n');}
inline void print(vector<ll> &vec){for(const auto t:vec)pt(t),putchar(' ');puts("");}
inline void print(const map<ll, ll>& g) {for(const auto& [key, value]:g){cout<<"key: "<<key<<" -> "<<value<<" ";}puts("");}
inline void print(vector<PLL> &vec){puts(sep);for(const auto v:vec){print(v);}puts(sep);}
inline void print(const map<ll, vector<ll>>& g) {for (const auto& [key, value] : g) { cout << "key: " << key << " -> ";for (const auto& v : value) {cout << v << " ";}cout << endl;}}
//fast pow
ll ksm(ll a, ll b=MOD-2,ll mod=MOD){a%=mod;ll res = 1;while(b){if(b&1){res=(res*a)%mod;}a=(a*a)%mod;b>>=1;}return res;}
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());//rng()
ull randint(ull l, ull r){uniform_int_distribution<unsigned long long> dist(l, r);return dist(rng);}
void init(){
}
void solve(){
}
int main(){
init();
ll t = 1;
t = read();
while(t--){
solve();
}
}