ABC268 VP 游记
引言
几天没比赛,手痒了,决定尝试 VP 一场 ABC,作为第一次 VP AT(
下次可能就不挑这么简单的场了(
VP 登顶留念。
比赛从 19:30 开始。我一路正开,也没啥罚时。
比赛题解
A
憨憨题。直接 sort
+ unique
即可。
std::vector<uint>A(5); for(auto&v:A)scanf("%u",&v); std::sort(A.begin(),A.end()); printf("%d\n",(int)(std::unique(A.begin(),A.end())-A.begin()));
B
憨憨题。直接做即可。
chr C1[205],C2[205]; scanf("%s%s",C1,C2); uint n=0; while(C1[n]){ if(C1[n]!=C2[n])return puts("No"),0; n++; } puts("Yes");
C
憨憨题。随便计算一下差量即可。
uint A[200005]; uint n;scanf("%u",&n); for(uint i=0,v;i<n;i++)scanf("%u",&v) ,A[(i+n-v)%n]++; uint ans=0; for(uint i=0;i<n;i++)_max(ans,A[i]+A[(i+1)%n]+A[(i+2)%n]); printf("%u\n",ans);
D
暴力 dfs 即可。
状态数可以预见不会很多。
细节有亿点多。
typedef std::vector<chr>str; std::set<str>S;str C[32],now;chr User[32];uint n;bol Used[32]; voi dfs(uint p){ if(now.size()>16)return; if(p==n){ for(uint i=0;i<n;i++)if(!Used[i]){ now.insert(now.end(),C[i].begin(),C[i].end()); if(now.size()>=3&&now.size()<=16&&!S.count(now)){ for(auto s:now)putchar(s); exit(0); } now.erase(now.end()-C[i].size(),now.end()); } return; } uint lim=18-now.size(); for(uint i=0;i<n;i++)if(!Used[i])lim-=C[i].size()+1; for(uint i=0;i<n;i++)if(!Used[i]){ Used[i]=1,now.insert(now.end(),C[i].begin(),C[i].end()); for(uint k=1;k<=lim;k++) { for(uint t=1;t<=k;t++)now.push_back('_'); dfs(p+1); now.erase(now.end()-k,now.end()); } now.erase(now.end()-C[i].size(),now.end()),Used[i]=0; } } int main() { #ifdef MYEE freopen("QAQ.in","r",stdin); // freopen("QAQ.out","w",stdout); #endif uint m;scanf("%u%u",&n,&m); for(uint i=0;i<n;i++){ scanf("%s",User); for(chr c:User)if(c)C[i].push_back(c);else break; } while(m--){ scanf("%s",User); for(chr c:User)if(c)now.push_back(c);else break; S.insert(now),now.clear(); } dfs(1); puts("-1"); return 0; }
E
还是考虑计算差量。
反向考虑对每种旋转方案的贡献,然后就是区间加一次函数。
直接用差分维护一下即可。
细节有亿点多。
ullt A[200005],B[200005];uint n; voi add_base(ullt*A,uint l,uint r,ullt v){A[r]-=v,A[l]+=v;} voi add(uint l,uint r,ullt k,ullt b){add_base(A,l,r,k),add_base(B,l,r,b);} voi add_all(int l,int r,ullt k,ullt b){ if(l<0) { add(l+n,n,k,b-n*k),add(0,r,k,b); return; } if(r>(int)n){ add(l,n,k,b),add(0,r-n,k,b+k*n); return; } add(l,r,k,b); } int main() { #ifdef MYEE freopen("QAQ.in","r",stdin); // freopen("QAQ.out","w",stdout); #endif scanf("%u",&n); for(uint i=0,v;i<n;i++){ scanf("%u",&v),v=(v+n-i)%n; add_all(v-n/2,v,-1llu,v); add_all(v,v+n-n/2,1llu,-(ullt)v); } for(uint i=0;i<n;i++)A[i+1]+=A[i],B[i+1]+=B[i]; ullt ans=-1; for(uint i=0;i<n;i++)_min(ans,A[i]*i+B[i]); printf("%llu\n",ans); return 0; }
F
国王游戏的经典调整法贪心。
typedef std::pair<ullt,ullt>Pair; chr C[200005];Pair P[200005]; uint n;ullt ans=0;scanf("%u",&n); for(uint i=0;i<n;i++){ scanf("%s",C); for(chr c:C)if(c){ if(c<='9')ans+=P[i].first*(c-'0'),P[i].second+=c-'0'; else P[i].first++; }else break; } std::sort(P,P+n,[&](Pair a,Pair b){ return a.first*b.second>a.second*b.first; }); ullt s=0; for(uint i=0;i<n;i++)ans+=s*P[i].second,s+=P[i].first; printf("%llu\n",ans);
G
考虑对排名反向计算贡献。
对 在 前的概率,有以下几种状态:
- 为 前缀,则 必然在 前。
- 为 前缀,则 必然在 后。
- 其余情况,前后顺序等可能出现。
直接拿棵 Trie 计算一下每个串有几个前缀出现在全集中,及作为全集中多少串的前缀。
然后随便统计一下信息就完了。
const ullt Mod=998244353; typedef ConstMod::mod_ullt<Mod>modint; struct node{node*son[26];uint v1,v2;}N[2000005],*rot=N,*cnt=N+1; node*NewNode(){return cnt++;} #define Id(p) ((uint)((p)-N)) #define Turn(c) ((c)-'a') node*insert(chr*C){ node*p=N; while(*C){ p->v1++;auto&s=p->son[Turn(*(C++))]; if(!s)s=NewNode(); p=s; } p->v2++; return p; } chr C[500005]; node*At[500005]; int main() { #ifdef MYEE freopen("QAQ.in","r",stdin); // freopen("QAQ.out","w",stdout); #endif uint n;scanf("%u",&n); for(uint i=0;i<n;i++)scanf("%s",C),At[i]=insert(C); for(node*p=rot;p!=cnt;p++)for(auto s:p->son)if(s)s->v2+=p->v2; for(uint i=0;i<n;i++){ (modint(n-At[i]->v1+At[i]->v2)/2).println(); } return 0; }
H
考虑对文本串每个前缀,计算出其最短的存在于模板串中的后缀。
这个拿个 ACAM 即可搞定。
然后就是每个这样的区间都得删掉一个点,直接贪心 / 差分约束即可。
const uint sigma=26; struct node{node*son[sigma],*fail;uint kill;node():kill(-1u){}}N[2000005],*rot=N,*cnt=N+1; node*NewNode(){return cnt++;} #define Id(p) ((uint)((p)-N)) #define Turn(c) ((c)-'a') voi insert(chr*C){ node*p=N;uint len=0; while(*C){ auto&s=p->son[Turn(*(C++))]; if(!s)s=NewNode(); p=s,len++; } _min(p->kill,len); } voi build(){ std::queue<node*>Q;rot->fail=rot; for(uint i=0;i<sigma;i++)(rot->son[i]?(Q.push(rot->son[i]),rot->son[i]->fail):rot->son[i])=rot; while(!Q.empty()){ node*p=Q.front();Q.pop(),_min(p->kill,p->fail->kill); for(uint i=0;i<sigma;i++) (p->son[i]?(Q.push(p->son[i]),p->son[i]->fail):p->son[i])=p->fail->son[i]; } } chr S[500005],C[500005]; int main() { #ifdef MYEE freopen("QAQ.in","r",stdin); // freopen("QAQ.out","w",stdout); #endif scanf("%s",S); uint n;scanf("%u",&n); while(n--){ scanf("%s",C); insert(C); } build(); uint ans=0,last=1e9; node*p=rot; for(auto c:S)if(c){ last++,p=p->son[Turn(c)]; if(last>=p->kill) last=0,ans++; }else break; printf("%u\n",ans); return 0; }
本文来自博客园,作者:myee,转载请注明原文链接:https://www.cnblogs.com/myee/p/VP-ABC268.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫