Educational Codeforces Round 33
A. Chess For Three
模拟
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
bool check(int x, int y, vi &A){
for(int &z : A){
int w = 0;
for(int i = 1; i <= 3; i++) if(i!=x and i!=y) w = i;
if(z==x) y = w;
else if(z==y) x = w;
else return false;
}
return true;
}
void solve(){
int n; sci(n);
vi A(n); for(int &x : A) sci(x);
if(!check(1,2,A)) cout <<"NO" << endl;
else cout << "YES" << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
B. Beautiful Divisors
枚举因子判断
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
bool check(int x){
vi A;
while(x){
A << x % 2;
x >>= 1;
}
int ptr = 0;
while(A[ptr]==0) ptr++;
for(int j = ptr; j < A.size(); j++) if(A[j]==0) return false;
return ptr * 2 + 1 == A.size();
}
void solve(){
int n; sci(n);
vi div;
for(int i = 1; i * i <= n; i++){
if(n%i!=0) continue;
div << i;
if(i!=n/i) div << n / i;
}
sort(all(div),greater<int>());
for(int &d : div) if(check(d)){
cout << d << endl;
return;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
C. Rumor
并查集,同时维护并查集中的最小值,最后把每个集合中的最小值加起来即可
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
int n, m, w[MAXN], f[MAXN];
int findx(int x){ return x == f[x] ? x : f[x] = findx(f[x]); }
void merge(int u, int v){
int x = findx(u), y = findx(v);
int ww = min(w[x], w[y]);
f[x] = y;
w[y] = ww;
}
void solve(){
sci(n); sci(m);
for(int i = 1; i <= n; i++) sci(w[i]);
for(int i = 1; i <= n; i++) f[i] = i;
for(int i = 1; i <= m; i++){
int u, v;
sci(u); sci(v);
if(findx(u) == findx(v)) continue;
merge(u,v);
}
LL ret = 0;
for(int i = 1; i <= n; i++) if(i==findx(i)) ret += w[i];
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
D. Credit Card
每次遇到\(0\)的时候先判断能否在之前的时候就加上
具体做法就是每次遇到\(0\)之后维护一个钱的最大值,只要保证在之前就把钱加上之后也不会超过限制就在之前把钱加上
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
void solve(){
int n, d;
sci(n); sci(d);
vi A(n); for(int &x : A) sci(x);
int cnt = 0;
int curmoney = 0;
int maxmoney = 1e9+7;
for(int i = 0; i < n; i++){
if(A[i]==0){
if(curmoney>=0) continue;
if(d - maxmoney >= -curmoney){
maxmoney -= curmoney;
curmoney = 0;
}else{
maxmoney = curmoney = 0;
cnt++;
}
}else{
if(curmoney + A[i] > d){
cout << -1 << endl;
return;
}
curmoney += A[i];
cmax(maxmoney,curmoney);
}
}
cout << cnt << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
E. Counting Arrays
先不管正负
分解质因子,然后每个质因子有若干次,把每个质因子分配到\(y\)个位置上去,假设某个质因子出现了\(a\)次,那么对于这个质因子的方案数就是\(\tbinom{y+a-1}{y-1}\)
前\(y-1\)个数的正负可以随便分,最后一个来决定正负即可,所以正负号的分配有\(2^{y-1}\)种
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e6+7;
const int MOD = 1e9+7;
int fac[MAXN], inv[MAXN], rfac[MAXN], pw[MAXN];
int C(int n, int m){ return n<m ? 0 : 1ll * fac[n] * rfac[m] % MOD * rfac[n-m] % MOD; }
void solve(){
int x, y; sci(x); sci(y);
vector<pii> vec;
for(int i = 2; i * i <= x; i++){
if(x%i!=0) continue;
vec << make_pair(i,0);
while(x%i==0) vec.back().second++, x /= i;
}
if(x!=1) vec << make_pair(x,1);
LL ret = 1;
for(auto p : vec) ret = 1ll * ret * C(y+p.second-1,y-1) % MOD;
ret = 1ll * ret * pw[y-1] % MOD;
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
fac[0] = rfac[0] = inv[1] = pw[0] = 1;
for(int i = 1; i < MAXN; i++) pw[i] = pw[i-1] * 2 % MOD;
for(int i = 1; i < MAXN; i++) fac[i] = 1ll * fac[i-1] * i % MOD;
for(int i = 2; i < MAXN; i++) inv[i] = 1ll * (MOD - MOD / i) * inv[MOD%i] % MOD;
for(int i = 1; i < MAXN; i++) rfac[i] = 1ll * rfac[i-1] * inv[i] % MOD;
int tt; for(sci(tt); tt--; solve());
return 0;
}
F. Subtree Minimum Query
线段树合并,只要记录各个深度下的最小值即可,最后询问深度在某个区间内的最小值就好了
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
int n, r, dep[MAXN], q, w[MAXN];
vi G[MAXN];
struct SegmentTree{
int root[MAXN], ls[MAXN<<5], rs[MAXN<<5], minn[MAXN<<5], tot;
void modify(int l, int r, int pos, int x, int &rt){
rt = ++tot;
minn[rt] = x;
if(l+1==r) return;
int mid = (l + r) >> 1;
if(pos < mid) modify(l,mid,pos,x,ls[rt]);
else modify(mid,r,pos,x,rs[rt]);
}
int merge(int u, int v, int l, int r){
if(!u or !v) return u^v;
if(l+1==r){
int rt = ++tot;
minn[rt] = min(minn[u],minn[v]);
return rt;
}
int rt = ++tot;
minn[rt] = INF;
int mid = (l + r) >> 1;
ls[rt] = merge(ls[u],ls[v],l,mid);
rs[rt] = merge(rs[u],rs[v],mid,r);
if(ls[rt]) cmin(minn[rt],minn[ls[rt]]);
if(rs[rt]) cmin(minn[rt],minn[rs[rt]]);
return rt;
}
int qmin(int rt, int l, int r, int L, int R){
if(L>=r or l>=R or !rt) return INF;
if(L<=l and r<=R) return minn[rt];
int mid = (l + r) >> 1;
return min(qmin(ls[rt],l,mid,L,R),qmin(rs[rt],mid,r,L,R));
}
}ST;
void dfs(int u, int par){
dep[u] = dep[par] + 1;
ST.modify(1,n+1,dep[u],w[u],ST.root[u]);
for(int v : G[u]){
if(v==par) continue;
dfs(v,u);
ST.root[u] = ST.merge(ST.root[u],ST.root[v],1,n+1);
}
}
void solve(){
sci(n); sci(r);
for(int i = 1; i <= n; i++) sci(w[i]);
for(int i = 1; i < n; i++){
int u, v; sci(u); sci(v);
G[u] << v; G[v] << u;
}
dfs(r,0);
sci(q);
int lastans = 0;
while(q--){
int x, k;
sci(x); sci(k);
x = (x + lastans) % n + 1;
k = (k + lastans) % n;
cmin(k,n-dep[x]);
printf("%d\n",lastans = ST.qmin(ST.root[x],1,n+1,dep[x],dep[x]+k+1));
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}