Problem - 349B - Codeforces,B - A < AP (atcoder.jp)

103 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 22 天,点击查看活动详情

Problem - 349B - Codeforces

位数越大是越优的,一开始写了个字符串版的背包然后MLE了,,,思路应该是找出位数最多且最大的数,然后再尽可能地用剩下的油漆去涂更大的数来替换当前的数

#include <bits/stdc++.h>
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
#define double long double
using namespace std;
const int mod=1000000007;
const int inf=1e9-1;
const int N=1e6+7;
string Max(string a,string b)
{
    if(a.size()>b.size()) return a;
    else if(b.size()>a.size()) return b;
    for(int i=0;i<a.size();i++)
    {
        if(a[i]>b[i]) return a;
        else if(a[i]<b[i]) return b;
    }
    return a;
}
int v,a[12];
signed main()
{
    cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
    //freopen("in.txt", "r", stdin);
    cin>>v;
    for(int i=1;i<=9;i++) cin>>a[i];
    int ma=10,minn=1e9;
    for(int i=1;i<=9;i++)
    if(a[i]<=v){ma=i;break;}
    if(ma>9)
    {
        cout<<"-1\n";return 0;
    }
    for(int i=1;i<=9;i++)
    {
        if(minn>=a[i]) minn=a[i],ma=i;
    }
    int n=v/minn,r=v%minn;
    vector<int>ans;
    while(n>=0&&r>=0)
    {
        int flag=0;
        for(int i=9;i>ma;i--)
        {
            if(a[i]-a[ma]<=r)
            {
                ans.push_back(i);
                n--;
                r=r-a[i]+a[ma];
                flag=1;
                break;
            }
        }
        if(flag==0) break;
    }
    for(auto x:ans) cout<<x;
    for(int i=1;i<=n;i++) cout<<ma;
    return 0;
}

B - A < AP (atcoder.jp)

假设A1=(a[p1],a[p2],,,a[pn]),X为A=A1的排列的个数,根据对称性A>A1和A<A1的个数应该是相等的,所以答案应该是(M^n-X)/2;

考虑A=A1的情况,分析一下样例可以发现如果我要让a[p[i]]等于y的话,那么我与之对应的a[i]也应该要等于y,将这样的i与p[i]连一条边最后会发现形成了若干个,设为c个连通分量,每个连通分量里的数都要取相同的值,那么A=A1的个数就好求了,就是X=M^c,那么答案也就是(M^n-M^c)/2;

#include <bits/stdc++.h>
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
#define double long double
using namespace std;
const int mod=998244353;
const int inf=1e9-1;
const int N=1e6+7;
int qpow(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
int getinv(int a){return qpow(a,mod-2);}
int n,m,vis[200005],p[200005],s[200005];
int findd(int x){return x==s[x]?x:s[x]=findd(s[x]);}
signed main()
{
    //cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
    //freopen("in.txt", "r", stdin);
    cin>>n>>m;
    for(int i=1;i<=n;i++) s[i]=i;
    for(int i=1;i<=n;i++)
    {
        cin>>p[i];
        int x=findd(i),y=findd(p[i]);
        if(x!=y) s[x]=y;
    }
    int c=0;
    for(int i=1;i<=n;i++)
    {
        int x=findd(i);
        if(!vis[x]) c++,vis[x]=1;
    }
    int ans=((qpow(m,n)-qpow(m,c))%mod+mod)%mod;
    ans=ans*getinv(2)%mod;
    cout<<ans<<endl;
    return 0;
}