Codeforces Round #785 (Div. 2)

Codeforces Round #785 (Div. 2)

B.A Perfectly Balanced String?

前面补下B比较坑
题意:给一个字符串,他的任意连续字串中任意两个字母出现次数只差不能大于1,
做法:首先考虑特殊情况,有相同字母连续出现,这种情况必然好判,然后考虑,其实只要任意两个相同字母之间所有位置字母都至少出现过一次,就满足上述题中条件了,赛中判了半天。。。

点击查看代码
#include <bits/stdc++.h>
using namespace std;

const int maxn=2e5+10;
typedef long long ll;

char s[maxn],s2[maxn];
int Sum[maxn][30];

int main(){
    #ifdef lmj_debug
        freopen("1.in","r",stdin);
    #endif

    int _;
    cin>>_;
    while(_--){
        scanf("%s",s+1);
        int len=strlen(s+1);
        ll ans=0;
        int num[30];
        memset(num,0,sizeof(num));
        int flag=0;
        vector<int>pos[30];
        for (int i=1;i<=len;i++) {
            for (int j=0;j<26;j++){
                Sum[i][j]=Sum[i-1][j];
            }
            Sum[i][s[i]-'a']++;
            pos[s[i]-'a'].push_back(i);
            num[s[i]-'a']++;
            if(s[i]==s[i-1]) flag=1;
        }
        int sum=0;
        for (int i=0;i<26;i++){
            if(num[i]) sum++;
        }
        if(sum==1){
            printf("YES\n");
            continue;
        }
        if(flag){
            printf("NO\n");
            continue;
        }
        if(sum==2){
            printf("YES\n");
        }else {
            bool flag2=0;
            for (int i=0;i<26;i++){
                for (int j=1;j<pos[i].size();j++){
                    int sz=2;
                    int l=pos[i][j-1];
                    int r=pos[i][j];
                    for (int k=0;k<26;k++){
                        if(Sum[r][k]-Sum[l-1][k]<=0 && num[k]) {flag2=1;break;}
                    }
                    if(flag2) break;
                }
                if(flag2) break;
            }
            if(flag2) printf("NO\n");
            else printf("YES\n");           
        }
    }
    return 0;
}

D.Lost Arithmetic Progression

题意:给两个等差数列B,C,求等差数列A,其中C是等差B,C的交集,求满足条件的等差数列A有多少个,一开始题意被我读错了,我认为是只要A,B中共同的元素C中有就可以了,题意原来是C必须是A,B的交集,那么这样的话就好想了
做法:既然C是A,B的交集,又都是等差数列,那么用\(d\)来表示公差,\(d_c\)必然是\(d_a,d_b\)的最小公倍数,且C必然是B的一部分,考虑0的情况,那么就要求(用\(A\)表示首项),\(A_c=A_b+k*d_b\),所以\(A_c-A_b\)\(d_b\)的倍数,且C的首项尾项必须在B的首项尾项之间,且\(d_c\)能整除\(d_b\)
考虑-1的情况,也就是存在无数解,这肯定是C的下一项或者首相往前的一项在B数列的范围之外
特殊情况考虑结束,考虑计数,枚举\(d_c\)的因子,其中满足最小公倍数条件的就是合法的\(d_a\),那么有多少个数列满足呢,等价于有多少对首项尾项满足,首项肯定只能在C的首项之前,为\(A_c-0,A_c-d_a,A_c-2*d_a..\)且不能超过\(A_c-d_c\)固共\(\frac{d_c}{d_a}\)项,对于尾项也一样,所以一共\({(\frac{d_c}{d_a})}^{2}\)

点击查看代码
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const ll mod=1e9+7;

inline ll gcd(ll a,ll b){
    if(b==0) return a;
    return gcd(b,a%b);
}

inline ll lcm(ll a,ll b){
    return a*b/gcd(a,b);
}

inline ll quickpow(ll a,ll b){
    ll ans=1;
    for (;b;b>>=1){
        if(b&1ll) ans=ans*a%mod;
        a=a*a%mod;
    }
    return ans;
}

int main(){
    #ifdef lmj_debug
        freopen("1.in","r",stdin);
    #endif
    int n;
    scanf("%d",&n);
    while(n--){
        long long a1,d1,c1;
        long long a2,d2,c2;
        cin>>a1>>d1>>c1>>a2>>d2>>c2;
        long long last1=a1+d1*(c1-1ll),last2=a2+d2*(c2-1ll);
        if((a2-a1)%d1 || d2%d1 || last2>last1 || a2<a1){
            puts("0");
            continue;
        }
        last2+=d2;
        if(a2-d2<a1 || last2>last1) {
            puts("-1");
            continue;
        }
        ll ans=0;
        for (ll x=1;x*x<=d2;x++){
            if(d2%x) continue;
            ll x1=x;
            if(lcm(x1,d1)==d2){
                ll p=d2*quickpow(x1,mod-2)%mod;
                ans=ans+p*p%mod;
                ans%=mod;
            }
            x1=d2/x;
            if(x1==x) continue;
            if(lcm(x1,d1)==d2){
                ll p=d2*quickpow(x1,mod-2)%mod;
                ans=ans+p*p%mod;
                ans%=mod;
            }
        }
        printf("%lld\n",ans%mod);
    }
    return 0;
}
posted @ 2022-05-01 21:31  lmj_1  阅读(60)  评论(0)    收藏  举报