Educational Codeforces Round 26
A. Text Volume
每个单词计算一下取个\(\max\)
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> void operator << (vector<T> &__container, T x){ __container.push_back(x); }
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; string s;
cin >> n;
cin.get();
getline(cin,s);
s.push_back(' ');
int maxx = 0;
for(int i = 0, cnt = 0; i < (int)s.length(); i++){
if(isalpha(s[i])){
if(s[i]>='A' and s[i]<='Z') cnt++;
continue;
}else cmax(maxx,cnt), cnt = 0;
}
cout << maxx << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
B. Flag of Berland
先判颜色是否都存在
然后找四个顶点,判一下是否矩形内都是某个颜色
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> void operator << (vector<T> &__container, T x){ __container.push_back(x); }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
char s[111][111];
int vec[111][111];
pair<pii,pii> A[3];
bool tag[3];
void solve(){
int n, m;
sci(n); sci(m);
for(int i = 1; i <= n; i++) scanf("%s",s[i]+1);
for(int i = 0; i < 3; i++) A[i] = {{1000,1000},{-1,-1}};
for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++){
if(s[i][j]=='R') vec[i][j] = 0, tag[0] = true;
if(s[i][j]=='G') vec[i][j] = 1, tag[1] = true;
if(s[i][j]=='B') vec[i][j] = 2, tag[2] = true;
}
if(!tag[0] or !tag[1] or !tag[2]){
cout << "NO" << endl;
return;
}
for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++){
int c = vec[i][j];
cmin(A[c].first.first,i);
cmax(A[c].second.first,i);
cmin(A[c].first.second,j);
cmax(A[c].second.second,j);
}
int w[3], h[3];
for(int i = 0; i < 3; i++){
w[i] = A[i].second.first - A[i].first.first;
h[i] = A[i].second.second - A[i].first.second;
}
for(int i = 0; i < 3; i++){
for(int x = A[i].first.first; x <= A[i].second.first; x++){
for(int y = A[i].first.second; y <= A[i].second.second; y++){
if(vec[x][y]!=i) {
cout << "NO" << endl;
return;
}
}
}
}
if(w[0]!=w[1] or w[1]!=w[2] or h[0]!=h[1] or h[1]!=h[2]){
cout << "NO" << endl;
return;
}
cout << "YES" << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
C. Two Seals
暴力枚举两个,各种姿势判断一下放不放的下
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> void operator << (vector<T> &__container, T x){ __container.push_back(x); }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 111;
int n, a, b;
bool check(int x, int y){ return (x<=a and y<=b) or (x<=b and y<=a); }
void solve(){
sci(n); sci(a); sci(b);
vector<pii> A(n);
for(auto &p : A) sci(p.first), sci(p.second);
int ret = 0;
for(int i = 0; i < n; i++) for(int j = i + 1; j < n; j++){
int x1 = A[i].first, x2 = A[j].first, y1 = A[i].second, y2 = A[j].second;
int area = x1 * y1 + x2 * y2;
if(check(x1+x2,max(y1,y2)) or check(y1+y2,max(x1,x2)) or check(x1+y2,max(x2,y1)) or check(x2+y1,max(x1,y2))) cmax(ret,area);
}
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
D. Round Subset
因子数不会很多
\(DP[i][j][k]\)表示考虑前\(i\)个数字,已经选了\(j\)个,因子\(5\)出现了\(k\)次的情况下,因子\(2\)出现的最多次数
可以把\(DP\)变成滚动数组
然后对于每个情况,后缀\(0\)的数量就是\(\min(cnt_2,cnt_5)\)
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> void operator << (vector<T> &__container, T x){ __container.push_back(x); }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
int f[2][205][6007];
void solve(){
int n, k; sci(n); sci(k);
vector<pii> A(n,{0,0});
for(int i = 0; i < n; i++){
LL x; scl(x);
while(x%2==0) x >>= 1, A[i].first++;
while(x%5==0) x /= 5, A[i].second++;
}
int tag = 0;
memset(f,255,sizeof(f));
f[0][0][0] = 0;
for(int i = 1; i <= n; i++){
tag ^= 1;
memcpy(f[tag],f[tag^1],sizeof f[tag]);
for(int j = 0; j <= min(i-1,k-1); j++){
for(int cnt_5 = 0; cnt_5 <= 6000; cnt_5++){
if(f[tag^1][j][cnt_5]==-1) continue;
cmax(f[tag][j+1][cnt_5+A[i-1].second],f[tag^1][j][cnt_5] + A[i-1].first);
}
}
}
int ret = 0;
for(int i = 1; i <= k; i++)for(int j = 0; j <= 6000; j++) if(f[tag][i][j]!=-1) cmax(ret,min(f[tag][i][j],j));
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
E. Vasya's Function
只要每次找到下一个\(gcd\)就好了
显然下一个\(gcd\)不会比当前的小,同时必然是当前\(gcd\)的倍数
所以不会超过\(\log x\)个,每次\(\sqrt x\)找即可
复杂度\(O(\sqrt x\log x)\)
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> void operator << (vector<T> &__container, T x){ __container.push_back(x); }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e6+7;
vl calf(LL x){
vl f;
for(LL i = 1; i * i <= x; i++){
if(x%i) continue;
f << i;
if(i!=x/i) f << x / i;
}
return f;
}
void solve(){
LL x, y;
scl(x); scl(y);
vl f = calf(x);
LL g = __gcd(x,y);
LL ret = 0;
while(y){
LL div = -1, mod = LLONG_MAX;
for(auto d : f){
if(d<=g or y%d%g!=0) continue;
if(y % d < mod or (y % d == mod and d > div)){
mod = y % d;
div = d;
}
}
if(div==-1) ret += y / g, y = 0;
else ret += y % div / g, y -= y % div, g = div;
}
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
F. Prefix Sums
求前缀和,把\(A^0\)看作一个多项式,那么求一次前缀和就相当于和\(\sum_{i=0}^{\infty} x^i=\frac 1{1-x}\)卷积
求\(m\)阶前缀和就相当于和\(\frac 1{(1-x)^m}\)做卷积
根据广义二项式定理可以得到\(\frac 1{(1-x)^m} = \sum_{i=0}^\infty \tbinom{i+m-1}{m-1}\)
而\(k\)阶前缀和的最大值显然是最后一个数,手动模拟最后一个位置的卷积判断是否大于\(k\)即可
那么我们可以考虑二分答案(前缀和阶数),然后判断就好了
注意爆\(long\ long\)的问题,这里考虑用\(long\ double\)来处理组合数,而且只要当前已经大于\(k\)了就提前跳出
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> void operator << (vector<T> &__container, T x){ __container.push_back(x); }
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;
LL k;
sci(n); scl(k);
vi A(n); for(int &x : A) sci(x);
for(int &x : A) if(x>=k){
cout << 0 << endl;
return;
}
LL l = 1, r = k;
auto check = [&](LL m){
long double sum = 0;
for(int i = 0; i < n; i++){
if(A[n-1-i]==0) continue;
LL nn = i + m - 1;
LL mm = min((LL)i,m-1);
long double comb = A[n-1-i];
for(LL x = 1, y = nn; x <= mm; x++, y--){
comb = comb * y / x;
if(comb>=k) return true;
}
sum += comb;
if(sum>=k) return true;
}
return false;
};
while(l<=r){
LL mid = (l + r) >> 1;
if(check(mid)) r = mid - 1;
else l = mid + 1;
}
cout << l << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
G. Functions On The Segments
每次查询可以把区间\([l,r]\)看作两个前缀和相减,那么问题转化为求前\(i\)个方程在\(x\)处的值了
考虑用主席树来做,把方程看作\(kx+b\),分别维护\(k\)和\(b\)
要做的就是把维护斜率的线段树的\([x_1+1,x_2]\)区间加\(a\),那么用差分的思路,在\(x_1+1\)的位置\(+a\),在\(x_2+1\)的位置\(-a\)即可
维护截距也是相同的,要在区间\([0,x1]\)加\(y_1\),区间\([x1+1,x2]\)加\(b\),区间\([x_2+1,\infty]\)加\(y_2\)
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;
const int MOD = 1e9;
int n, q;
struct SegmentTree{
LL sum[MAXN<<6];
int ls[MAXN<<6], rs[MAXN<<6], tot, root[MAXN];
void modify(int &rt, int pre, int pos, int x, int l, int r){
rt = ++tot;
sum[rt] = sum[pre]; ls[rt] = ls[pre]; rs[rt] = rs[pre];
sum[rt] += x;
if(l+1==r) return;
int mid = (l + r) >> 1;
if(pos<mid) modify(ls[rt],ls[pre],pos,x,l,mid);
else modify(rs[rt],rs[pre],pos,x,mid,r);
}
LL qsum(int L, int R, int l, int r, int rt){
if(L>=r or l>=R) return 0;
if(L<=l and r<=R) return sum[rt];
int mid = (l + r) >> 1;
return qsum(L,R,l,mid,ls[rt]) + qsum(L,R,mid,r,rs[rt]);
}
}ST[2];
LL f(int r, int x){ return ST[0].qsum(0,x+1,0,MAXN,ST[0].root[r]) * x + ST[1].qsum(0,x+1,0,MAXN,ST[1].root[r]); }
void solve(){
sci(n);
for(int i = 1; i <= n; i++){
int x1, x2, y1, a, b, y2;
sci(x1); sci(x2); sci(y1); sci(a); sci(b); sci(y2);
int rt, tmp;
ST[0].modify(rt,ST[0].root[i-1],x1+1,a,0,MAXN);
ST[0].modify(ST[0].root[i],rt,x2+1,-a,0,MAXN);
ST[1].modify(rt,ST[1].root[i-1],0,y1,0,MAXN);
ST[1].modify(tmp,rt,x1+1,b-y1,0,MAXN);
ST[1].modify(ST[1].root[i],tmp,x2+1,y2-b,0,MAXN);
}
sci(q); LL lastans = 0;
while(q--){
int l, r, x;
sci(l); sci(r); sci(x);
x = (x + lastans) % MOD;
cout << (lastans = f(r,x) - f(l-1,x)) << endl;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
下面是\(T\)了第\(23\)个点的分块做法
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 = 1e5 + 7;
const int MOD = 1e9;
int n, m, q, sqt, bel[MAXN], l[MAXN], r[MAXN];
struct Function{ int x1, x2, y1, a, b, y2; }f[MAXN];
vector<int> vec[MAXN];
vector<pll> func[MAXN];
void process(int id){
vector<pii> vcc;
for(int i = l[id]; i <= r[id]; i++) vcc << pii(f[i].x1 + 1,i) << pii(f[i].x2 + 1,i);
vcc << pii(0,0);
sort(all(vcc));
LL a = 0, b = 0;
for(int i = l[id]; i <= r[id]; i++) b += f[i].y1;
func[id] << pll(a,b); vec[id] << 0;
int ptr = 1;
while(ptr < (int)vcc.size()){
int rptr = ptr;
while(rptr < (int)vcc.size() and vcc[rptr].first==vcc[ptr].first){
if(vcc[rptr].first==f[vcc[rptr].second].x1+1){
a += f[vcc[rptr].second].a;
b += f[vcc[rptr].second].b - f[vcc[rptr].second].y1;
}else{
a -= f[vcc[rptr].second].a;
b -= f[vcc[rptr].second].b - f[vcc[rptr].second].y2;
}
rptr++;
}
func[id] << pll(a,b); vec[id] << vcc[ptr].first;
ptr = rptr;
}
}
void solve(){
sci(n); sqt = pow(n,0.67);
m = n / sqt + (n % sqt == 0 ? 0 : 1);
for(int i = 1; i <= n; i++) sci(f[i].x1), sci(f[i].x2), sci(f[i].y1), sci(f[i].a), sci(f[i].b), sci(f[i].y2);
for(int i = 1; i <= m; i++) l[i] = (i - 1) * sqt + 1, r[i] = i * sqt;
r[m] = n;
for(int i = 1; i <= m; i++) for(int j = l[i]; j <= r[i]; j++) bel[j] = i;
for(int i = 1; i <= m; i++) process(i);
sci(q);
LL lastans = 0;
while(q--){
int lt, rt, x;
sci(lt), sci(rt), sci(x);
x = (x + lastans) % MOD;
lastans = 0;
if(bel[lt]==bel[rt]){
for(int i = lt; i <= rt; i++){
if(x<=f[i].x1) lastans += f[i].y1;
else if(x<=f[i].x2) lastans += f[i].a * x + f[i].b;
else lastans += f[i].y2;
}
}else{
for(int i = lt; i <= r[bel[lt]]; i++){
if(x<=f[i].x1) lastans += f[i].y1;
else if(x<=f[i].x2) lastans += f[i].a * x + f[i].b;
else lastans += f[i].y2;
}
for(int i = l[bel[rt]]; i <= rt; i++){
if(x<=f[i].x1) lastans += f[i].y1;
else if(x<=f[i].x2) lastans += f[i].a * x + f[i].b;
else lastans += f[i].y2;
}
for(int i = bel[lt] + 1; i <= bel[rt] - 1; i++){
auto p = upper_bound(all(vec[i]),x) - vec[i].begin() - 1;
lastans += func[i][p].first * x + func[i][p].second;
}
}
cout << lastans << endl;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}