Codeforces Round #655 题解

https://codeforces.com/contest/1372

A

众所周知,(1+1 eq 1)

所以输出 (n)(1) 即可。

时间复杂度 (O(tn))

#include <bits/stdc++.h>
using namespace std;
int t;
int n;
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            printf("1 ");
        puts("");
    }
    return 0;
}

B

(x)(n) 最小的质因数。

此时答案为 (frac{n}{x},n-frac{n}{x})

于是可以 (O(sqrt{n})) 解决每组数据。

#include <bits/stdc++.h>
using namespace std;
int t;
int n,fl;
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        fl=1;
        for(int i=2;i*i<=n;i++)
            if(n%i==0) {
                printf("%d %d
",n/i,n-n/i);
                fl=0;
                break;
            }
        if(fl)
            printf("%d %d
",1,n-1);
    }
    return 0;
}

C

考虑将每个数按在不在自己的位置归类。

找到所有不在自己的位置的段的个数即可。

于是您就 WA 了。

如果有若干段不在自己的位置的段的话,可以考虑把所有位置全部打乱,再一一对应。

时间复杂度:(O(tn))

#include <bits/stdc++.h>
using namespace std;
int t;
int n,a[200010],fl;
long long ans;
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        ans=0;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=2;i<=n;i++)
            if(a[i]==i&&a[i-1]!=i-1)
                ans++;
        if(a[n]!=n)
            ans++;
        if(ans>2)
            ans=2;
        printf("%d
",ans);
    }
    return 0;
}

D

这个出题人我点个赞!

看到环形,就能想到破环为链,先破掉。

然后呢?

找规律 txdy!

捏组样例看看:

1 2 3 4 5 6 7
(2+7) 3 4 5 6 // 对 1 处进行操作
3 4 (5+2+7) // 对 6 处进行操作
3+5+2+7 //对 4 处进行操作

考虑对答案的贡献的数,似乎没规律的样子。

可是一条链的视角来看呢?

1 2 (3) 4 (5) 6 (7) 1 (2) 3 4 5 6 7

可以猜测,对于任意的环而言,均有这样的规律。

所以,我们可以求出下标均为奇数,长度为 (frac{n+1}{2}) 的连续子序列。

对偶数也一样。

求连续子序列的和可以使用 (l,r) 两个指针。

时间复杂度 (O(n))

#include <bits/stdc++.h>
using namespace std;
int t,l,r;
int n,a[400010],k;
long long ans,sum;
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
        a[i+n]=a[i];
    k=(n+1)/2-1;
    l=1,r=l+k*2;
    for(int i=l;i<=r;i+=2)
        sum+=a[i];
    ans=max(ans,sum);
    while(r<=2*n) {
        l+=2,r+=2;
        sum-=a[l-2];
        sum+=a[r];
        ans=max(ans,sum);
    }
    l=2,r=l+k*2;
    sum=0;
    for(int i=l;i<=r;i+=2)
        sum+=a[i];
    ans=max(ans,sum);
    while(r<=2*n) {
        l+=2,r+=2;
        sum-=a[l-2];
        sum+=a[r];
        ans=max(ans,sum);
    }
    printf("%lld
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/lajiccf/p/CF655.html