2022牛客暑期多校训练营9 个人题解

57 篇文章 0 订阅
38 篇文章 0 订阅

title :2022牛客暑期多校训练营9 题解
date : 2022-9-24
tags : ACM,练习记录
author : Linno


2022牛客暑期多校训练营9 题解

题目链接 :https://ac.nowcoder.com/acm/contest/33194

补题进度 :5/11

第八场太难了,不写。

A-Car Show

双指针即可,也就是枚举r,然后将l向右移使得刚好包含m个数,那么l向左的所有位置都是合法的。

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#define inf 0x3f3f3f3f
#define int long long

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
const int N=2e5+7;
const int mod=1e9+7;

int n,m,a[N],vis[N],cnt[N];

void Solve(){
	cin>>n>>m;
	for(int i=0;i<=m;++i) vis[i]=cnt[i]=0;
	for(int i=1;i<=n;++i) cin>>a[i];
	int l=1,r=0,flag=0;
	while(r<n&&flag!=m){
		++r;
		++cnt[a[r]];
		if(!vis[a[r]]) vis[a[r]]=1,flag++;
	}
	if(flag!=m){
		cout<<0<<"\n";
		return;
	}
	int ans=0;
	while(l<=n){
		ans+=n-r+1;
		cnt[a[l]]--;
		if(cnt[a[l]]==0){
			while(r<n&&!cnt[a[l]]){
				++r;
				++cnt[a[r]];
			}
			if(cnt[a[l]]==0) break;
		}
		++l;
	}
	cout<<ans<<"\n";
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
//  freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
//	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;
	return 0;
}


B-Two Frogs

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
int a[100005];
ll dp[100005];
ll inv[100005];
ll tt[100005];
inline ll pp(ll a,ll b) {
	if(a+b>=mod)
		return a+b-mod;
	else return a+b;
}
int n;
inline ll qpow(ll a,int b) {
	ll ans=1;
	while(b) {
		if(b&1) {
			ans=(ans*a)%mod;
		}
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}
ll tree[200005];
inline int lowbit(int i) {
	return i & (-i);
}
inline void modify(int i, ll k) {
	int x = i;
	while(i <= n) {
		tree[i]=pp(tree[i],k);
		i += lowbit(i);
	}
}

inline ll query(int i) {
	ll x = i, res = 0;
	while(i) {
		res=pp(res,tree[i]);
		i -= lowbit(i);
	}
	return res;
}
int main() {
	scanf("%d",&n);
	for(int i=1; i<=n; ++i)
		scanf("%d",&a[i]),inv[i]=qpow(a[i],mod-2);
	dp[1]=1;
	int maxx=1;
	for(int j=2; j<=n; ++j) {
		for(int i=1; i<n; ++i) {
			if(dp[i]!=0) {
				ll t=inv[i]*dp[i]%mod;
				modify(i+1,t);
				if(i+a[i]<n) {
					modify(i+a[i]+1,mod-t);
				}
			}
		}
		for(int i=1; i<n; ++i) {
			dp[i]=query(i);
		}
		ll zz=query(n);
		dp[n]=pp(dp[n],zz*zz%mod);
		memset(tree,0,sizeof(tree));
	}
	printf("%lld",dp[n]);
	return 0;
}

E-Longest Increasing Subsequence

#include <bits/stdc++.h>
using namespace std;
int main() {
	int tt;
	scanf("%d",&tt);
	while(tt--) {
		int m;
		scanf("%d",&m);
		if(m==1) {
			printf("1\n1\n");
			continue;
		}
		int pos[105];
		int c[106];
		int cc=0;
		while(m) {
			if(m&1) {
				c[++cc]=1;
			} else c[++cc]=0;
			m>>=1;
		}
		int kt[105];
		for(int i=1; i<=cc; ++i) {
			kt[i]=c[cc-i+1];
		}
		for(int i=1; i<=cc; ++i)
			c[i]=kt[i];
		int all=0;
		int cnt=0;
		int t[106];
		for(int i=1; i<=cc; ++i) {
			if(c[i]) {
				t[i]=i-all;
				all=i;
			} else t[i]=0;
		}
		int kk=0;
		int tt=0;
		for(int i=1; i<=cc; ++i) {
			if(c[i]) {
				for(int j=1; j<=t[i]; ++j) {
					pos[++kk]=2*cc-2+all;
					all--;
				}
			}
			if(i<cc) {
				pos[++kk]=2*(cc-i)-1;
				pos[++kk]=2*(cc-i);
			}
		}
		printf("%d\n",kk);
		for(int i=kk; i>=1; --i) {
			printf("%d%c",pos[i],(i==1)?'\n':' ');
		}
	}
	return 0;
}

G-Magic Spells

对每个串都建一个回文自动机,然后在上面跑dfs即可。

#include<bits/stdc++.h>
using namespace std;
const int N=6e5+7;

int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}

int n,m,f[N][10],ans=0;
char s[N];
int ch[N][26],fa[N],len[N];
/*vector<int>e[N];
struct G_PAM{
	int ch[26],fa,len;
}tr[N];
*/
struct E{
	int v,nxt;
}e[N<<1];
int ecnt=0,head[N];
inline void addedge(int u,int v){e[++ecnt]=(E){v,head[u]};head[u]=ecnt;}
int lst,cnt=1;

inline void init(){
	s[0]=-1;
	len[1]=-1;
	fa[0]=fa[1]=1;
	//tr[1].len=-1;
	//tr[0].fa=tr[1].fa=1;
	lst=0;
}
inline void insert(int k,int c,int id){
	int p=lst;
	while(s[k-len[p]-1]!=c+'a')p=fa[p];
	if(!ch[p][c]) {
		int q=lst=++cnt,v=fa[p];
		while(s[k-len[v]-1]!=c+'a') v=fa[v];
		fa[q]=ch[v][c];
		len[ch[p][c]=q]=len[p]+2;
	} else lst=ch[p][c];
	f[lst][id]++;
}
inline void dfs(int x){
	//for(int i=0;i<e[x].size();++i){
	for(int i=head[x];i;i=e[i].nxt){
		int y=e[i].v;
		dfs(y);
		for(int k=0;k<n;++k){
			f[x][k]+=f[y][k];
		}
	}
	int flag=0;
	for(int k=0;k<n;++k) if(!f[x][k]) flag=1;
	if(x==1||x==0||flag) return;
	ans++;
}

signed main(){
	scanf("%d",&n);
	for(int i=0;i<n;++i){
		init();
		scanf("%s",s);
		for(int j=0;j<strlen(s);++j) insert(j,s[j]-'a',i);
	}
	addedge(1,0);
	for(int i=2;i<=cnt;++i) addedge(fa[i],i);
	dfs(1);
	write(ans),putchar('\n');
	return 0;
}

I-The Great Wall II

#include <bits/stdc++.h>
using namespace std;
long long n,a[1000005],dp[8008][8008];
int main()
{
	cin>>n;
	for (int i=1;i<=n;++i)
	scanf("%lld",&a[i]);
	for (int i=0;i<=n;++i)
	for (int j=0;j<=n;++j)
		dp[i][j]=1e9;
	dp[0][0]=0;
	for (int i=1;i<=n;++i)
	{
		stack< pair<int,long long> > q;
		for (int j=1;j<=n;++j)
		{
			long long mi=dp[i-1][j-1];
			while ( q.size() && a[q.top().first] <= a[j])
			{
				mi=min(mi,q.top().second);
				q.pop();
			}
			int pre=0;
			if (q.size()) pre=q.top().first;
			dp[i][j]=min(dp[i][pre],mi+a[j]);
			q.push( make_pair(j,mi) );
		}
	}
	for (int i=1;i<=n;++i)
	printf("%lld\n",dp[i][n]);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RWLinno

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值