一道纯纯的思维题。
很考验观察能力与思维能力。
题目链接。
题意
现在有 个集合 ,每个集合内都是在 中的整数。
如果我们称一组集合
是辉煌的,当且仅当:
对于每一个 ,在 与
中只出现一次的数,恰好都只有一个。
对于一组集合,我们定义它的权值为 。
求所有辉煌的集合的权值和。
题解
因为相邻两个集合中只有一个数字不同,我们设第 个集合和第 集合中,不同的那个数为 。
首先我们会有一个结论:
确定了 和所有 ,就可以确定其他的 。
显然,若
已经确定,则可以通过 得知 的值(如果 ,令 ,否则,令 就行)
稍微推广一下:
假如确定了所有 ,那么一共有
中不同的 。
这个也比较显然,因为 只有
不同的选法,选定 就相当于选定了所有 。
然后我们设两个序列 ,分别表示 存在数字 和不存在数字 时,有多少个集合包含数字 。
显然,有 。
下面是重点:
假如我们已经选定了一组 。
那么显然,假如
为空的贡献权值为 ,只有一个数字
时权值为 。
所以我们可以推出,此时所有方案的权值和为 。
而我们一共有 中不同
的取值。
所以最终答案为 。
时间复杂度是 。
然而 都是 。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include<algorithm> #include<cstring> #include<cstdio> #include<vector> #include<queue> #include<map> using namespace std; const int mod=998244353; using ll=long long; using pli=pair<ll,int>; using pi=pair<int,int>; template<typename A> using vc=vector<A>; inline int read() { int s=0,w=1;char ch; while((ch=getchar())>'9'||ch<'0') if(ch=='-') w=-1; while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } ll qow(ll a,int b) { ll ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } int main() { int n=read(),m=read(); printf("%lld\n",qow(n,m)*qow(m,n-1)%mod); return 0; }
|
感谢观看!