萌新第三次参加比赛了。。慢慢懂了一些套路。这次发挥比之前都好,比赛中做出了三道题,排名是2400多。写一下前四道题的题解:
A. New Year Garland(思维)
三种颜色的灯笼排列成一条直线,直线上任意邻近的灯笼颜色不同。
给出三种灯笼的数量,判断能否满足如上条件。
解:两种灯笼的数量之和小于数量最大的灯笼个数-1就可以满足条件。复杂度O(1)
代码略
B. Verse For Santa(前缀和)
解:第i个verse的前缀和与S比较,小于等于S的话ans=0,大于S的话减去0~i个verse中的最大值再与S比较,小于等于S的话ans=最大值的下标。复杂度O(n).
代码:
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cstdio>
#include<cstring>
#include<string>
#define MAXN 100
#define For(x,y) for(int x=1;x<=y;x++)
using namespace std;
long long s[100005];
int main(){
int t;
cin>>t;
long long n,S,maxx,ans,index;
while(t--){
s[0]=0;
maxx=0;
ans=0;
scanf("%lld%lld",&n,&S);
For(i,n){
scanf("%lld",s+i);
if(s[i]>maxx)index=i,maxx=s[i];
s[i]+=s[i-1];
if(s[i]<=S)ans=0;
else if(s[i]-maxx<=S)ans=index;
}
cout<<ans<<endl;
}
return 0;
}
C. Stack of Presents(思维)
解:存储bi在a中对应的下标,遍历bi,每次取bi时,把bi+1,bi+2..中连续的出现在bi之前的数都放在最上面,这样这些数每次只需要动一下。复杂度O(m)
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cstdio>
#include<cstring>
#include<string>
#define MAXN 100
#define For(x,y) for(int x=0;x<y;x++)
using namespace std;
int b[100005],a[100005];
int main(){
int t;
cin>>t;
int n,m,now;
int bi,bnow;
long long sum;
while(t--){
scanf("%d%d",&n,&m);
For(i,n)scanf("%d",&now),a[now]=i;
For(i,m)scanf("%d",b+i),b[i]=a[b[i]];
bi=0,sum=0;
while(bi<m){
bnow=b[bi];
sum+=2*(bnow-bi)+1;
bi++;
while(bi<m&&b[bi]<bnow)sum++,bi++;
}
cout<<sum<<endl;
}
return 0;
}
D.Santa's Bot(概率+逆元)
解:
一开始往组合数的方向想没整出来,后来看大神的代码发现就是简单的概率求和.....
做出有效决定的概率=每一个礼物被选中时为有效决定的概率之和
设p[j]为想要j礼物的人数,j礼物被选中一次且有效的概率是1/n(n个孩子选第i个)*1/ki(i孩子想要的k个礼物中选这个礼物)*p[j]/n(j礼物有效的概率),可以发现1/n可以提取,ki可以求和,这样复杂度就简化到了O(NlogMOD)
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#define MAXN 1000002
#define For(x,y) for(int x=0;x<y;x++)
#define MOD 998244353
using namespace std;
long long a[MAXN],p[MAXN];
long long inv(long long n){
long long m=MOD-2,s=1;
while(m){
if(m&1)s=s*n%MOD;
m>>=1;
n=n*n%MOD;
}
return s;
}
int main(){
ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
long long ki,n,k,now;
cin>>n;
memset(a,0,sizeof(a));
memset(p,0,sizeof(p));
For(i,n){
cin>>k;
ki=inv(k)%MOD;
For(j,k){
cin>>now;
a[now]=(a[now]+ki)%MOD,p[now]++;
}
}
long long P=0;
For(i,MAXN)
if(p[i])
P=(P+a[i]*inv(n)%MOD*inv(n)%MOD*p[i]%MOD)%MOD;
cout<<P;
return 0;
}