开启掘金成长之旅!这是我参与「掘金日新计划 · 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;
}