P9753 [CSP-S 2023] 消消乐 题解
不用栈也不用map。
考虑预处理。 处理 a 数组,每次走到一个位置 i,往前搜索。 当前位置不等于 i 则通过这个位置继续往前查找。一直到当前位置等于 i,或者到达最前端则停止。 接下来进行第二次处理。 由于已经对 a 进行过预处理,在计算时只需要从有值的点分别往前统计即可。 最后求一遍和。
感谢学弟 @kibi 的优化!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include<bits/stdc++.h> using namespace std; #define int long long const int N = 2000010; int n, a[N], f[N],tot; char s[N]; signed main() { memset (a, -1, sizeof a); cin>>n; for ( int i=1;i<=n;i++) cin>>s[i]; for ( int i=1;i<=n;i++) a[i]=i-1; for ( int i=1;i<=n;i++){ while (s[a[i]]!=s[i]) { a[i]=a[a[i]]-1; if (a[i]<=-1) break ; } } // for(int i=1;i<=n;i++) cout<<a[i]<<' '; // cout<<endl; for ( int i=1;i<=n;i++) { if (a[i]>0) f[i]=f[a[i]-1]+1; } for ( int i=1;i<=n;i++) { tot+=f[i]; } cout<<tot<<endl; } |
加强版:CF1223F Stack Exterminable Arrays - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
直接使用上面的思路,发现前四个点跑得飞快,但tle on #5。
考虑在上面的思路的基础上进行剪枝。
观察每一次往回预处理上一个出现位置的情况。
若查找位置已经小于当前这个数字最早出现的坐标,此时可以将这个值改为-1然后break。
这样就少了很多重复查询的过程,不容易被卡到 O(n2)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include<bits/stdc++.h> using namespace std; #define int long long const int N = 300010; int n, a[N], f[N],tot; int s[N]; int t; int vis[N]; signed main() { memset (vis, 0x3f3f3f3f, sizeof vis); memset (a,-1, sizeof a); cin>>t; while (t--) { tot=0; cin>>n; for ( int i=1;i<=n;i++){ cin>>s[i],f[i]=0; vis[s[i]]=min(vis[s[i]],i); } f[0]=0; for ( int i=1;i<=n;i++) a[i]=i-1; for ( int i=1;i<=n;i++){ while (s[a[i]]!=s[i]) { a[i]=a[a[i]]-1; if (a[i]<=-1) break ; if (vis[s[i]]>a[i]){ a[i]=-1; break ; } } } for ( int i=1;i<=n;i++) { if (a[i]>0) f[i]=f[a[i]-1]+1; } for ( int i=1;i<=n;i++) { tot+=f[i]; } cout<<tot<<endl; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!