题意:给你序列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]<
- }
-
相关阅读:
.NET数据交互之生成和读取YAML文件
P3743 kotori的设备
Ubuntu出现无法获取 dpkg 前端锁 (/var/lib/dpkg/lock-frontend),是否有其他进程正占用它?
心电贴技术方案芯片LH001-91
嵌入式Linux驱动开发6---sysfs文件系统与 kobject结构体
如何保护应用?可快速部署的WAF服务器分享
C++智能指针shared_ptr用法
dubbo解析-详解元数据中心MetadataReport
什么是鱼叉式网络钓鱼?
决策树分男女性别
-
原文地址:https://blog.csdn.net/m0_55032066/article/details/127853556