题意:给你序列a,问有多少序列b满足对于所有的区间[l,r]最左最大的值所在位置与a相同。
分析:想到了找最大值所在的位置分治,但一直不懂n*m<=1e6有什么用,根本就没想二叉树。想到了就是个简单树dp。
代码:
- int a[maxn];
- int n,m;
- map<int,int>dp[maxn],pre[maxn];
- int table1[maxn][maxlog];
-
- void ppre()
- {
- for(int st=1;(1<
- {
- for(int i=1;i+(1<
-1<=n;i++) - {
- table1[i][st]=a[table1[i][st-1]]>=a[table1[i+(1<<(st-1))][st-1]]?table1[i][st-1]:table1[i+(1<<(st-1))][st-1];
- }
- }
- }
-
- int askmax(int l,int r)
- {
- int st=log2(r-l+1);
- return a[table1[l][st]]>=a[table1[r-(1<
1][st]]?table1[l][st]:table1[r-(1<1][st]; - }
-
- int dfs(int l,int r,int x)
- {
- if(l>r) return -1;
- int u=askmax(l,r);
- int v1=dfs(l,u-1,x-1),v2=dfs(u+1,r,x);
-
- for(int i=1;i<=x;i++)
- {
- int prev1=1,prev2=1;
- if(v1!=-1) prev1=pre[v1][i-1];
- if(v2!=-1) prev2=pre[v2][i];
- dp[u][i]=prev1*prev2%mod;
-
- pre[u][i]=(pre[u][i-1]+dp[u][i])%mod;
- }
-
- return u;
- }
-
- void solve()
- {
- cin>>n>>m;
- for(int i=1;i<=n;i++) dp[i].clear(),pre[i].clear();
- for(int i=1;i<=n;i++) cin>>a[i],table1[i][0]=i;
- ppre();
- cout<
dfs(1,n,m)][m]<
- }
-
相关阅读:
Js写的二级联动和三级联动
asp毕业设计——基于asp+access的校园网物品交易平台设计与实现(毕业论文+程序源码)——校园网物品交易平台
Zabbix 5.0 升级到 6.0LTS
动态规划合集
linux tasks errors
【深度好文】到底什么是质量意识?如何衡量,如何提升?
charles安装使用
Linux_API_系列-整体概览
Unity游戏Mod/插件制作教程04 - 如何创建配置文件
https 和 tcp 的关系
-
原文地址:https://blog.csdn.net/m0_55032066/article/details/127853556