Educational Codeforces Round 26

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;
}
posted @ 2020-08-23 21:51  _kiko  阅读(149)  评论(0编辑  收藏  举报