ABC298 CDE Solution- shengbinhao

shengbinhao 2023-07-07 21:47:49 2023-07-20 21:28:57 7


我们可以用 setmultiset 来分别维护 cardbox

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
multiset<int> box[N];
set<int> c[N];
int n,q,i,j,o;
signed main(){
	
	cin>>n>>q;
	while(q--){
		cin>>o;
		if(o==1){
			cin>>i>>j;
			box[j].insert(i);
			c[i].insert(j);
		}
		else if(o==2){
			cin>>i;
			for(auto k:box[i]) cout<<k<<" ";
			cout<<"\n";
		}
		else {
			cin>>i;
			for(auto k:c[i]) cout<<k<<" ";
			cout<<"\n";
		}
	}
	
	
	
	return 0;
}

数字的操作我们可以用队列来维护。 因为数字很大,那么该怎么算结果呢?

我们可以一边算一边操作。

设现在答案为ans

  • 加入操作:
  • 删除操作:首位数字的贡献

首位数字的贡献可以一边操作一边维护,乘

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
queue<int> q;
int Q,o,x,inv,ans=1,f=1;
int ksm(int a,int b,int m){
	if(b==0) return 1;
	if(b==1) return a%m;
	int t=ksm(a,b/2,m)%m;
	t=t*t%m;
	if(b%2) t=t*a%m;
	return t;
}
signed main(){
	
	inv=ksm(10,mod-2,mod);
	q.push(1);
	cin>>Q;
	while(Q--){
		cin>>o;
		if(o==1){
			cin>>x;
			q.push(x);
			ans=(ans*10+x)%mod;
			f=(f*10)%mod;
		}
		else if(o==2){
			ans=((ans-f*q.front()%mod)+mod)%mod;
			q.pop();
			f=f*inv%mod;
		}
		else cout<<ans<<"\n";
	}
	
	
	
	
	return 0;
}

因为数据范围小,想怎么搞就怎么搞。

两个人的位置都只会前进不会后退,可以用 表示达成“ 走到 走到 这个局面” 的概率。

所以说,我们可以使用递推。到最后再来统计获胜局面的概率之和就行了。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
int n,A,B,q,P;
int inv[15];
int p[110][110];
signed main(){
	
	cin>>n>>A>>B>>P>>q;
	
	inv[1]=1;
	for(int i=2;i<=10;++i){
		inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	}
	p[A][B]=1;
	for(int a=A;a<=n;a++){
		for(int b=B;b<=n;b++){
			if(a==n||b==n) break;
			for(int i=1;i<=P;++i){
				for(int j=1;j<=q;++j){
					p[min(a+i,n)][min(b+j,n)]=(p[min(a+i,n)][min(b+j,n)]+(inv[P]*inv[q]%mod)*p[a][b])%mod;
				}
			}
		}
	}
	
	int ans=0;
	for(int i=1;i<=n;++i){
		ans=(ans+p[n][i])%mod;
	}
	
	cout<<ans%mod<<"\n";
	
	return 0;
}
{{ vote && vote.total.up }}