cf1189div2解题报告

codeforces

A

答案要不是一串要不就是去掉最后一个字母的两串

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=107;
int a[N<<2],n;
int main() {
    scanf("%d",&n);
    int js=0;
    for(int i=1;i<=n;++i) {
        scanf("%1d",&a[i]);
        js+=a[i];
    }
    if(n!=1&&js==n-js) {
        printf("2\n");
        for(int i=1;i<n;++i) printf("%d",a[i]);
        printf(" ");
        printf("%d",a[n]);
    } else {
        printf("1\n");
        for(int i=1;i<=n;++i) printf("%d",a[i]);
    }
    return 0;
}

B

cf好喜欢构造呀。
\(1-3-5-7-9-10-8-6-4-2\)
这样构造应该是最优解。
然后check输出

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+7;
int n,a[N],b[N];
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;++i) {
        scanf("%d",&a[i]);
    }
    sort(a+1,a+1+n);
    int js=0;
    for(int i=1;i<=n;i+=2) b[++js]=a[i];
    for(int i=(n&1)?n-1:n;i>=1;i-=2) b[++js]=a[i];
    b[0]=b[n],b[n+1]=a[1];
    for(int i=1;i<=n;++i)
        if(b[i]>=b[i-1]+b[i+1]) return puts("NO"),0;
    puts("YES");
    for(int i=1;i<=n;++i)
        printf("%d ",b[i]);
    return 0;
}

C

虽然有很短的代码,但我还是写了线段树,好***啊

#include <bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int N=2e5+7;
int n,m,ans,tot[N<<2],sum[N<<2];
void build(int l,int r,int rt) {
    if(l==r) {
        scanf("%d",&tot[rt]);
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,ls);
    build(mid+1,r,rs);
    tot[rt]=(tot[ls]+tot[rs])%10;
    sum[rt]=sum[ls]+sum[rs]+((tot[ls]+tot[rs])>=10);
//  printf("sum[%d]=%d tot=%d\n",rt,sum[rt],tot[rt]);
}
int query(int l,int r,int L,int R,int rt) {
    if(L<=l&&r<=R) {
        ans+=sum[rt];
        return tot[rt];
    }
    int mid=(l+r)>>1;
    if(L<=mid&&R>mid) {
        int a=query(l,mid,L,R,ls);
        int b=query(mid+1,r,L,R,rs);
        if(a+b>=10) ans++;
        return (a+b)%10;
    } else if(L<=mid) return query(l,mid,L,R,ls);
    else return query(mid+1,r,L,R,rs);
}
int main() {
    scanf("%d",&n);
    build(1,n,1);
    scanf("%d",&m);
    for(int i=1,l,r;i<=m;++i) {
        scanf("%d%d",&l,&r);
        ans=0;
        int tmp=query(1,n,l,r,1);
        printf("%d\n",ans);
    }
    return 0;
}

D1

使得一颗树上边的权值任意,只要不出现度数为2的点就行。

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int n,ru[N];
int main() {
    scanf("%d",&n);
    for(int i=1;i<n;++i) {
        int l,r;
        scanf("%d%d",&l,&r);
        ru[l]++,ru[r]++;
    }
    for(int i=1;i<=n;++i)
        if(ru[i]==2) return puts("NO"),0;
    puts("YES");
    return 0;
}

E

\[(a_i + a_j)(a_i^2 + a_j^2) \equiv k \bmod p \]
\[a_i^3 + a_i^2a_j+a_ia_j^2 + a_j^3 \equiv k \bmod p\]
左右乘\((a_i-a_j)\)
\[a_i^4 - a_j^4 \equiv ka_i-ka_j \bmod p\]
\[a_i^4 - ka_i \equiv a_j^4-ka_j \bmod p\]
map统计答案就行了

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e5+7;
int n,k,p,a[N];
unordered_map<int,int> Hash;
int pow4(int a) {return 1LL*a*a%p*a%p*a%p;}
int main() {
    scanf("%d%d%d",&n,&p,&k);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    ll ans=0;
    for(int i=1;i<=n;++i) {
        int tmp=((pow4(a[i])-1LL*k*a[i]%p)%p+p)%p;
        ans+=Hash[tmp];
        Hash[tmp]++;
    }
    cout<<ans<<"\n";
    return 0;
}