Thanks for joining us today! Here is the editorial for today's problems:
1478A - Nezzar и разноцветные шары
Tutorial
Tutorial is loading...
Solution
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i=0;i<(int)(n);++i)
#define rep1(i,n) for (int i=1;i<=(int)(n);++i)
#define range(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define pb push_back
#define F first
#define S second
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int maxn=200007;
int t,n;
int cnt[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin>>t;
while (t--){
cin>>n;
rep1(i,n) cnt[i]=0;
rep1(i,n){
int u;
cin>>u;
cnt[u]++;
}
int mx=0;
rep1(i,n) mx=max(mx,cnt[i]);
cout<<mx<<"\n";
}
return 0;
}
1478B - Nezzar и счастливые числа
Tutorial
Tutorial is loading...
Solution
#include<bits/stdc++.h>
using namespace std;
const int maxn=207;
int t,d,q;
bool dp[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin>>t;
while (t--){
memset(dp,0,sizeof(dp));
dp[0]=1;
cin>>q>>d;
if (!d) d+=10;
int mx=d*10;
for (int i=0;10*i+d<=mx;++i){
for (int j=0;10*i+d+j<=mx;++j){
dp[10*i+d+j]|=dp[j];
}
}
while (q--){
int u;
cin>>u;
if (u>=mx||dp[u]) cout<<"YES\n";
else cout<<"NO\n";
}
}
return 0;
}
1478C - Nezzar и симметричный массив
Tutorial
Tutorial is loading...
Solution
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=200007;
int t;
int n,a[maxn],b[maxn],d[maxn];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin>>t;
while (t--){
cin>>n;
for (int i=0;i<2*n;++i) cin>>a[i];
sort(a,a+2*n,greater<int>());
for (int i=0;i<n;++i){
if (a[i*2]!=a[i*2+1]){
cout<<"NO\n";
goto cont;
}
b[i]=a[i*2];
}
for (int i=1;i<n;++i){
if (b[i-1]==b[i]||(b[i-1]-b[i])%(2*(n-i))){
cout<<"NO\n";
goto cont;
}
d[i]=(b[i-1]-b[i])/2/(n-i);
}
for (int i=1;i<n;++i){
b[n-1]-=2*i*d[i];
}
if (b[n-1]<=0||b[n-1]%(2*n)) cout<<"NO\n";
else cout<<"YES\n";
cont:;
}
return 0;
}
Tutorial
Tutorial is loading...
Solution
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=200007;
int t;
int n,k;
int x[maxn];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin>>t;
while (t--){
cin>>n>>k;
for (int i=0;i<n;++i) cin>>x[i];
sort(x,x+n);
int g=0;
for (int i=1;i<n;++i){
g=__gcd(g,x[i]-x[0]);
}
if ((k-x[0])%g) cout<<"NO\n";
else cout<<"YES\n";
}
return 0;
}
1477B - Nezzar и бинарная строка
Tutorial
Tutorial is loading...
Solution
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i=0;i<(int)(n);++i)
#define rep1(i,n) for (int i=1;i<=(int)(n);++i)
#define range(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define pb push_back
#define F first
#define S second
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int maxn=200007;
set<int> seg; // segment: [seg[i],seg[i+1])
int n,q,t,prv;
int l[maxn],r[maxn];
bool val[maxn];
string s;
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin>>t;
while (t--){
cin>>n>>q;
cin>>s;
rep(i,q) cin>>l[i]>>r[i], l[i]--;
reverse(l,l+q), reverse(r,r+q);
seg.clear();
rep(i,n) seg.insert(i), val[i]=s[i]-'0';
seg.insert(n);
auto add=[&](int u){
if (seg.find(u)==seg.end()){
auto ret=*prev(seg.upper_bound(u));
val[u]=val[ret];
seg.insert(u);
}
};
rep(i,q){
add(l[i]), add(r[i]);
vi remv;
remv.clear();
int sum[2];
memset(sum,0,sizeof(sum));
auto iter=seg.find(l[i]);
while (1){
if (*iter==r[i]) break;
int prev=*iter;
iter=next(iter);
if (*iter<r[i]) remv.pb(*iter);
sum[val[prev]]+=*iter-prev;
}
if (sum[0]==sum[1]){
cout<<"-\n";
goto cont;
}
if (sum[0]<sum[1]) val[l[i]]=1;
else val[l[i]]=0;
for (auto c:remv) seg.erase(c);
}
prv=0;
for (auto c:seg){
if (!c) continue;
for (int i=prv;i<c;++i) cout<<val[prv];
prv=c;
}
cout<<"\n";
cont:;
}
}
1477C - Nezzar и красивая карта
Tutorial
Tutorial is loading...
Solution
#include<bits/stdc++.h>
using namespace std;
const int maxn=6007;
int n;
int x[maxn],y[maxn];
vector<int> perm;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin>>n;
for (int i=0;i<n;++i) cin>>x[i]>>y[i];
for (int i=0;i<n;++i){
perm.push_back(i);
for (int j=i;j>1;--j){
if (1ll*(x[perm[j]]-x[perm[j-1]])*(x[perm[j-1]]-x[perm[j-2]])+1ll*(y[perm[j]]-y[perm[j-1]])*(y[perm[j-1]]-y[perm[j-2]])>=0){
swap(perm[j],perm[j-1]);
}
else{
break;
}
}
}
for (auto c:perm) cout<<c+1<<" ";
}
1477D - Nezzar и тайные перестановки
Tutorial
Tutorial is loading...
Solution
#include<bits/stdc++.h>
using namespace std;
const int maxn=500007;
struct info{
int idx,val;
friend bool operator<(info u,info v){
return u.val==v.val?u.idx<v.idx:u.val<v.val;
}
};
struct stars{
int rt;
vector<int> leaves;
};
set<int> rv; // remained vertices
set<int> g[maxn]; // original graph
set<int> t[maxn]; // dfs tree
set<info> d;
int deg[maxn];
int n,m;
int perm1[maxn],perm2[maxn];
vector<stars> res;
void dfs(int u){
rv.erase(u);
int crt=0;
while (1){
auto iter=rv.upper_bound(crt);
if (iter==rv.end()) break;
int v=*iter;
crt=v;
if (g[u].find(v)!=g[u].end()) continue;
t[u].insert(v), t[v].insert(u);
dfs(v);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int tc;
cin>>tc;
while (tc--){
cin>>n>>m;
for (int i=1;i<=n;++i) g[i].clear(), t[i].clear();
rv.clear(), res.clear(), d.clear();
for (int i=1;i<=m;++i){
int u,v;
cin>>u>>v;
g[u].insert(v), g[v].insert(u);
}
for (int i=1;i<=n;++i) rv.insert(i);
while (rv.size()>0){
int u=*(rv.begin());
dfs(u);
}
int rem=n;
for (int i=1;i<=n;++i){
deg[i]=t[i].size();
if (deg[i]){
d.insert((info){i,deg[i]});
}
else{
perm1[i]=perm2[i]=rem;
rem--;
}
}
while (d.size()){
int idx=(*(d.begin())).idx;
int f=*(t[idx].begin());
vector<int> leaves;
leaves.clear();
d.erase((info){f,deg[f]});
for (auto c:t[f]){
d.erase((info){c,deg[c]});
if (deg[c]==1) leaves.push_back(c);
else deg[c]--, d.insert((info){c,deg[c]}), t[c].erase(f);
}
res.push_back((stars){f,leaves});
}
int l=0,r=0;
for (auto c:res){
perm1[c.rt]=++l;
for (auto ls:c.leaves){
perm1[ls]=++l;
perm2[ls]=++r;
}
perm2[c.rt]=++r;
}
for (int i=1;i<=n;++i) cout<<perm1[i]<<" ";
cout<<"\n";
for (int i=1;i<=n;++i) cout<<perm2[i]<<" ";
cout<<"\n";
}
}
Tutorial
Tutorial is loading...
Solution
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i=0;i<(int)(n);++i)
#define rep1(i,n) for (int i=1;i<=(int)(n);++i)
#define range(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define pb push_back
#define F first
#define S second
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
namespace internal {
// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
int x = 0;
while ((1U << x) < (unsigned int)(n)) x++;
return x;
}
}
template <class S, S (*op)(S, S), S (*e)()> struct segtree {
public:
segtree() : segtree(0) {}
segtree(int n) : segtree(std::vector<S>(n, e())) {}
segtree(const std::vector<S>& v) : _n(int(v.size())) {
log = internal::ceil_pow2(_n);
size = 1 << log;
d = std::vector<S>(2 * size, e());
for (int i = 0; i < _n; i++) d[size + i] = v[i];
for (int i = size - 1; i >= 1; i--) {
update(i);
}
}
void set(int p, S x) {
assert(0 <= p && p < _n);
p += size;
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
S get(int p) {
assert(0 <= p && p < _n);
return d[p + size];
}
S prod(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
S sml = e(), smr = e();
l += size;
r += size;
while (l < r) {
if (l & 1) sml = op(sml, d[l++]);
if (r & 1) smr = op(d[--r], smr);
l >>= 1;
r >>= 1;
}
return op(sml, smr);
}
S all_prod() { return d[1]; }
template <bool (*f)(S)> int max_right(int l) {
return max_right(l, [](S x) { return f(x); });
}
template <class F> int max_right(int l, F f) {
assert(0 <= l && l <= _n);
assert(f(e()));
if (l == _n) return _n;
l += size;
S sm = e();
do {
while (l % 2 == 0) l >>= 1;
if (!f(op(sm, d[l]))) {
while (l < size) {
l = (2 * l);
if (f(op(sm, d[l]))) {
sm = op(sm, d[l]);
l++;
}
}
return l - size;
}
sm = op(sm, d[l]);
l++;
} while ((l & -l) != l);
return _n;
}
template <bool (*f)(S)> int min_left(int r) {
return min_left(r, [](S x) { return f(x); });
}
template <class F> int min_left(int r, F f) {
assert(0 <= r && r <= _n);
assert(f(e()));
if (r == 0) return 0;
r += size;
S sm = e();
do {
r--;
while (r > 1 && (r % 2)) r >>= 1;
if (!f(op(d[r], sm))) {
while (r < size) {
r = (2 * r + 1);
if (f(op(d[r], sm))) {
sm = op(d[r], sm);
r--;
}
}
return r + 1 - size;
}
sm = op(d[r], sm);
} while ((r & -r) != r);
return 0;
}
private:
int _n, size, log;
std::vector<S> d;
void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};
const int maxn=500007;
const int maxm=1000007;
int n,m,k,q,t;
ll sum;
int a[maxn],b[maxn];
struct S{
int cnt;
ll sum;
};
S e(){
return {0,0};
}
S op(S l,S r){
return {l.cnt+r.cnt,l.sum+r.sum};
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
segtree<S,op,e> seg_a(maxm),seg_b(maxm);
auto fa=[&](int x){
if (x>m||x<=0) cerr<<x<<endl;
assert(x<=m&&x>0);
return seg_a.max_right(0,[&](S l){return l.cnt<x;});
};
auto fb=[&](int x){
assert(x<=n&&x>0);
return seg_b.max_right(0,[&](S l){return l.cnt<x;});
};
auto solve=[&](int start,int coef){
// cerr<<"start coef:"<<start<<" "<<coef<<endl;
int mn=min(fa(1),fb(1));
if (start<=k+mn) return 1ll*(n-m)*start+sum;
auto ret=seg_b.prod(0,start-k);
// cerr<<"ret:"<<ret.cnt<<" "<<ret.sum<<endl;
return 1ll*coef*(start-k-mn)+1ll*(n-m)*start+sum+ret.sum-1ll*ret.cnt*(start-k);
};
cin>>m>>n>>q;
rep1(i,m) {cin>>a[i],sum+=a[i]; auto ret=seg_a.get(a[i]); ret.cnt++, ret.sum+=a[i], seg_a.set(a[i],ret);}
rep1(i,n) {cin>>b[i],sum-=b[i]; auto ret=seg_b.get(b[i]); ret.cnt++, ret.sum+=b[i], seg_b.set(b[i],ret);}
sum+=1ll*(m-n)*k;
auto res=[&](){
ll ans=-1e15;
ans=max(ans,solve(fb(1),m));
ans=max(ans,solve(fb(n),m));
ans=max(ans,solve(fa(1),m-1));
ans=max(ans,solve(fa(m),m-1));
int threshold=n>1?fb(n-1):0;
if (k+threshold<=1e6){
int pos=max(seg_a.prod(0,k+threshold).cnt,1);
ans=max(ans,solve(fa(pos),m-1));
int nxt_pos=seg_a.max_right(0,[&](S l){return l.cnt<=pos;});
if (nxt_pos<maxm) ans=max(ans,solve(nxt_pos,m-1));
}
cout<<ans<<"\n";
};
while (q--){
int op,idx,x;
cin>>op;
if (op==1){
cin>>idx>>x;
auto ret=seg_a.get(a[idx]);
ret.cnt--, ret.sum-=a[idx];
seg_a.set(a[idx],ret);
sum-=a[idx];
sum+=x;
a[idx]=x;
ret=seg_a.get(x);
ret.cnt++, ret.sum+=x;
seg_a.set(x,ret);
}
if (op==2){
cin>>idx>>x;
auto ret=seg_b.get(b[idx]);
ret.cnt--, ret.sum-=b[idx];
seg_b.set(b[idx],ret);
sum+=b[idx];
sum-=x;
b[idx]=x;
ret=seg_b.get(x);
ret.cnt++, ret.sum+=x;
seg_b.set(x,ret);
}
if (op==3){
cin>>k;
sum+=(m-n)*k;
res();
sum-=(m-n)*k;
}
}
return 0;
}
1477F - Nezzar и шоколадные плитки
Tutorial
Tutorial is loading...
Solution
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
#define rep(i,n) for (int i=0;i<(int)(n);++i)
#define rep1(i,n) for (int i=1;i<=(int)(n);++i)
#define range(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define pb push_back
#define F first
#define S second
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
const ll mod = (119 << 23) + 1, root = 62; // = 998244353
// For p < 2^30 there is also e.g. 5 << 25, 7 << 26, 479 << 21
// and 483 << 21 (same root). The last two are > 10^9.
ll modpow(ll b, ll e) {
ll ans = 1;
for (; e; b = b * b % mod, e /= 2)
if (e & 1) ans = ans * b % mod;
return ans;
}
typedef vector<ll> vl;
void ntt(vl &a) {
int n = sz(a), L = 31 - __builtin_clz(n);
static vl rt(2, 1);
for (static int k = 2, s = 2; k < n; k *= 2, s++) {
rt.resize(n);
ll z[] = {1, modpow(root, mod >> s)};
for(int i=k;i<2*k;++i) rt[i] = rt[i / 2] * z[i & 1] % mod;
}
vi rev(n);
for(int i = 0; i < n; ++i) rev[i] = (rev[i / 2] | (i & 1) << L) / 2;
for(int i = 0; i < n; ++i) if (i < rev[i]) swap(a[i], a[rev[i]]);
for (int k = 1; k < n; k *= 2)
for (int i = 0; i < n; i += 2 * k) for(int j = 0; j < k; ++j) {
ll z = rt[j + k] * a[i + j + k] % mod, &ai = a[i + j];
a[i + j + k] = ai - z + (z > ai ? mod : 0);
ai += (ai + z >= mod ? z - mod : z);
}
}
vl conv(const vl &a, const vl &b) {
if (a.empty() || b.empty()) return {};
int s = sz(a) + sz(b) - 1, B = 32 - __builtin_clz(s), n = 1 << B;
int inv = modpow(n, mod - 2);
vl L(a), R(b), out(n);
L.resize(n), R.resize(n);
ntt(L), ntt(R);
for (int i = 0; i < n; ++i) out[-i & (n - 1)] = (ll)L[i] * R[i] % mod * inv % mod;
ntt(out);
return {out.begin(), out.begin() + s};
}
const int maxn=1007;
int n,k;
int l[maxn];
struct polynomial{
int n,m;
vector<vi> poly;
polynomial(vector<vi> &po):poly(po){
n = sz(poly) - 1, m = sz(poly[0]) - 1;
}
vi rsz(int nn,int mm){
assert(nn>n&&mm>m);
vi ret;
ret.resize(nn*mm+1,0);
for (int i=0;i<=n;++i){
for (int j=0;j<=m;++j){
ret[i*mm+j]=poly[i][j];
assert(poly[i][j]<mod&&poly[i][j]>=0);
}
}
return ret;
}
friend polynomial operator*(polynomial l,polynomial r){
vector<vi> po;
po.clear();
po.resize(l.n+r.n+1,vi(l.m+r.m+1,0));
auto lpo=l.rsz(l.n+1,l.m+r.m+1),rpo=r.rsz(r.n+1,l.m+r.m+1),res=conv(lpo,rpo);
// for (auto c:res) cout<<c<<" ";
// cout<<endl;
// cout<<sz(lpo)<<" "<<sz(rpo)<<" "<<sz(res)<<endl;
for (int i=0;i<=l.n+r.n;++i){
for (int j=0;j<=l.m+r.m;++j){
po[i][j]=res[i*(l.m+r.m+1)+j];
}
}
// cout<<"hi"<<endl;
return po;
}
};
vector<polynomial> poly;
int f[5007];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin>>n>>k;
f[0]=1;
rep1(i,5000) f[i]=f[i-1]*i%mod;
int L=0;
rep(i,n) cin>>l[i], L+=l[i];
rep(i,n){
vi res0,res1;
res0.clear(), res1.clear();
res0.pb(1), res1.pb(0);
int sgn=1;
rep1(j,l[i]/k){
int tmp0,tmp1;
sgn=-sgn;
if (l[i]==k*j) {
tmp0=tmp1=0;
}
else{
tmp0=(modpow((l[i]-k*j)*modpow(L,mod-2)%mod,j)%mod)*modpow(f[j],mod-2)%mod, tmp1=(modpow((l[i]-k*j)*modpow(L,mod-2)%mod,j-1)%mod)*modpow(f[j-1],mod-2)%mod;
if (sgn<0) tmp0=(tmp0?mod-tmp0:tmp0), tmp1=(tmp1?mod-tmp1:tmp1);
}
// cerr<<i<<" "<<j<<":"<<tmp0<<" "<<tmp1<<endl;
res0.pb(tmp0), res1.pb(tmp1);
}
vector<vi> p({res0,res1});
polynomial po(p);
poly.pb(po);
}
for (int k=1;k<=n;k<<=1){
for (int i=k;i<n;i+=2*k){
poly[i-k]=poly[i]*poly[i-k];
}
}
int ans=0;
// x^{j-i}exp((1-k*j/L)) -> (j-i)!/((k*j/L)^{j-i+1}) = (j-i)!L^{j-i+1}/(k*j)^{j-i+1}
rep(i,poly[0].n+1){
rep(j,poly[0].m+1){
if (i>j) {assert(poly[0].poly[i][j]==0); continue;}
if (j==0) {assert(poly[0].poly[i][j]==1); continue;}
if (k*j==L) {assert(poly[0].poly[i][j]==0); continue;}
int num=f[j-i]*modpow(L,j-i+1)%mod,den=modpow(k*j,j-i+1)%mod;
// cerr<<i<<","<<j<<":"<<poly[0].poly[i][j]<<" "<<num<<" "<<den<<endl;
ans=(ans+(num*modpow(den,mod-2)%mod)*poly[0].poly[i][j]%mod)%mod;
}
}
if (ans>0) cout<<mod-ans<<endl;
else cout<<0<<endl;
return 0;
}