Codeforces Edu Round 58 A-E

A. Minimum Integer

  1. 如果\(d < l\),则\(d\)满足条件
  2. 否则,输出\(d * (r / d + 1)\)即可。
#include <cstdio>
#include <iostream>
using namespace std;
int main(){
    int T; scanf("%d", &T);
    while(T--){
        int l, r, d; scanf("%d%d%d", &l, &r, &d);
        if(d < l) printf("%d\n", d);
        else printf("%d\n", d * (r / d + 1));
    }
    return 0;
}

B. Accordion

找到头尾的\([:\)\(:]\),然后统计中间有几个\(|\)即可。

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N = 500010;
int n;
char s[N];
int main(){
    scanf("%s", s + 1);
    n = strlen(s + 1);
    int l = 1, r = n, cnt = 0;
    while(l <= n && s[l] != '[') l++;
    while(r && s[r] != ']') r--;
    while(l <= n && s[l] != ':') l++;
    while(r && s[r] != ':') r--;
    if(l >= r) puts("-1");
    else{
        for(int i = l; i <= r; i++)
            if(s[i] == '|') cnt++;
        printf("%d\n", 4 + cnt);
    }
    
    
    return 0;
}

C. Division and Union

发现可以竖着一条线将所有线分开成两部分,则两边任意选都可以。那么我们就可以找到这个条线。把线段按左端点排序,每次如果有交集就合并,没有交集,我们就找到了一个"断点"。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 100010;
int n, l[N], r[N];
PII a[N];
int main(){
    int T; scanf("%d", &T);
    while(T--){
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            scanf("%d%d", l + i, r + i);
            a[i].first = l[i];
            a[i].second = r[i];
        }
        sort(a + 1, a + 1 + n);
        int rr = a[1].second, loc = 0;
        for(int i = 2; i <= n; i++){
            if(a[i].first <= rr)
                rr = max(rr, a[i].second);
            else { loc = rr; break; }
        }
        if(!loc) printf("-1");
        else for(int i = 1; i <= n; i++)
            if(r[i] <= rr) printf("1 ");
            else printf("2 ");
        puts("");
    }
    return 0;
}

D. GCD Counting

树形\(dp\)\(100000\)以内的每个数因子不超过\(256\)个(最多\(2 ^ 3 * 3 * 5 * 7 * 9 * 13 * 19 > 100000\)

首先把每个读入的权值质因数分解,两个数必须有质因子\(gcd\)才不会$ = 1\(。存在一条边\)(u, v)\(,若\)u\(和\)v$之间有相同的质因子则可以合并,但注意下一次合并必须也有这个质因子...

所以设计\(f[i][j]\)\(i\)个点为根节点,以第\(j\)个质因子为保障的最大长度。更新显然,如果遇到新的更新,答案可以更新,现在的 + 可以更新的。

所以... 虽然看似会炸掉,但是还是卡过了...

#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
const int N = 200010;
int n, a[N], ans = 1;
vector<int> G[N], p[N], f[N];
bool success = true;
void dfs(int u, int last){
    for(int i = 0; i < G[u].size(); i++){
        int v = G[u][i];
        if(v == last) continue;
        dfs(v, u);
        for(int j = 0; j < p[u].size(); j++){
            for(int k = 0; k < p[v].size(); k++){
                if(p[u][j] == p[v][k]){
                    ans = max(ans, f[u][j] + f[v][k]);
                    f[u][j] = max(f[u][j], f[v][k] + 1);
                }
            }
        }
    }
}
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", a + i);
        if(a[i] != 1) success = false;
        int x = a[i];
        for(int j = 2; j * j <= a[i]; j++){
            if(x % j == 0){
                p[i].push_back(j);
                f[i].push_back(1);
                while(x % j == 0) x /= j;
            }
        }
        if(x > 1) p[i].push_back(x), f[i].push_back(1);
    
    }
    for(int i = 1; i < n; i++){
        int u, v; scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    if(success) puts("0");
    else{
        dfs(1, 0);
        printf("%d", ans);
    }
    return 0;
}

E. Polycarp's New Job

两者都符合交换律,所以我们交换使得:

\(x <= y\)\(h <= w\)

维护\(x\)\(y\)的最大值,\(max\_x\)\(max\_y\)

检查$max_x <= h $ \(\&\&\) \(max\_y <= w\)即可。

显然,如果符合$max_y <= h $ \(\&\&\) \(max\_x <= w\),那么前者显然必然成立:

如果不符合,前者也有可能成立。

#include <cstdio>
#include <iostream>
using namespace std;
const int N = 500010;
int n, a = 0, b = 0;
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        char ch; cin >> ch;
        if(ch == '+'){
            int x, y; scanf("%d%d", &x, &y);
            if(x > y) swap(x, y);
            a = max(a, x);
            b = max(b, y);
        }else{
            int h, w; scanf("%d%d", &h, &w);
            if(h > w) swap(h, w);
            if(a <= h && b <= w) puts("YES");
            else puts("NO");
        }
    }
    return 0;
}
posted @ 2019-08-02 22:25  DMoRanSky  阅读(122)  评论(0编辑  收藏  举报