title :2022牛客暑期多校训练营9 题解
date : 2022-9-24
tags : ACM,练习记录
author : Linno
2022牛客暑期多校训练营9 题解
题目链接 :https://ac.nowcoder.com/acm/contest/33194
补题进度 :5/11
第八场太难了,不写。
文章目录
- 2022牛客暑期多校训练营9 题解
- [A-Car Show](https://ac.nowcoder.com/acm/contest/33194/A)
- [B-Two Frogs](https://ac.nowcoder.com/acm/contest/33194/B)
- [E-Longest Increasing Subsequence](https://ac.nowcoder.com/acm/contest/33194/E)
- [G-Magic Spells](https://ac.nowcoder.com/acm/contest/33194/G)
- [I-The Great Wall II](https://ac.nowcoder.com/acm/contest/33194/I)
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;
}