VP CF1121
TL;DR 拉完了,A题写了半小时+2发罚时,真的闹闹又麻麻,我真笑了。然后C题以为树上问题想了半年,突然发现条件太松了,可以化为序列问题做递推,然后秒了。总拉完了。D然后就没时间咯~
总之C题展现数值,A题展现神人本质
A#
警钟长鸣啊
B#
依旧警钟长鸣————推式子认真点,被再写错正负号了,浪费时间TV。😅
然后发现set.end()居然不能--,比较震撼,顺便查了下set维护一些东西的用法。
set <int> s;
multiset <int> ms;
s.insert();
s.erase();//by 值 or 迭代器
int mn = *s.begin(); // 最小
int mx = *s.rbegin(); // 最大
大于等于 xxx 的最小 s.lower_bound(x) it != s.end()
严格大于 xxx 的最小 s.upper_bound(x) it != s.end()
严格小于 xxx 的最大 prev(s.lower_bound(x)) s.lower_bound(x) != s.begin()
小于等于 xxx 的最大 prev(s.upper_bound(x)) s.upper_bound(x) != s.begin()
注意条件,包括set.empty(),能否找到?,prev(it),it是不是在s.begin()?
C#
有点意思,初看以为树上DP,一看1e5,根是fixed的,一开始在考虑枚举树的结构,但发现这个太蠢了,做不到。
突然发现,如果把数组降序排序,那么新加入的点可以加到任意一个原来树上的节点,考虑同时维护到前 个点加入树的总答案和方案数目。方案数的转移时 (已经加入的点的数量),答案的转移,两部分,第一部分是对于前 的某一个方案,现在都有 种加法,那么原来的树相当于也复制了(先复制很多副本,在被 连在不同的节点),在加入连边的贡献即可。
注意C++对负数取余有问题,-1%3不会等于2,所以减也要+mod (重庆B趣事)
#include <bits/stdc++.h>
#define int long long
#define N 200005
using namespace std;
int a[N],mod=998244353;
bool cmp(int x,int y){
return x>y;
}
signed main (){
int T,n;
cin>>T;
while (T--){
cin>>n;
for (int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n,cmp);
int ans=0,cnt=1,sum=a[1];
for (int i=2;i<=n;i++){
ans=(ans*(i-1)%mod+cnt*(sum-(i-1)*a[i]%mod+mod)%mod)%mod;
cnt=cnt*(i-1)%mod;
sum=(sum+a[i])%mod;
}
cout<<ans<<endl;
}
return 0;
}