正题

题目链接:https://www.luogu.com.cn/problem/P3352


题目大意

\(n\)个数字的一个序列,每次随机选择一个区间让这个区间所有数等于这个区间的最大值,重复\(q\)次,对每个位置求所有情况下这个位置的值的和。

\(1\leq n,q\leq 400\),保证数据随机


解题思路

设\(f_{k,l,r}\)表示使用了\(k\)次目前覆盖了极大区间\(l,r\)时的方案。

这个极大区间就是无法继续向左右扩展(就是左右两边是边界或者比这个区间内所有数都大),不然相同的方案会统计入不同的数组导致算重。

然后每次我们找一个数字开始向左右扩展到极大区间进行\(dp\),然后\(dp\)方程是

\[f_{k,l,r}=f_{k-1,l,r}\times g_{l,r}+\sum_{i=L}^{l-1}f_{k-1,i,r}+\sum_{i=r+1}^{R}f_{k-1,l,i+1}
\]

也就是固定端点的情况下扩展极大区间,因为是反过来的所以这样是对的。

然后记录一个\(dp\)数组\(ans_{i,j}\)表示数字\(i\)至少为第\(j\)小的情况数,这个每次\(dp\)后都可以统计。

上面每个\(dp\)区间相当于笛卡尔树上的区间,因为数据随机,所以每个位置只会计算\(log\)次。

时间复杂度\(O(nq^2+n^3)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=410,P=1e9+7;
ll n,q,a[N],b[N],rk[N],f[2][N][N],ans[N][N],cnt[N];
void solve(ll x,ll L,ll R){
for(ll i=L;i<=R;i++)
for(ll j=i;j<=R;j++)
f[0][i][j]=f[1][i][j]=0;
f[0][L][R]=1;
for(ll k=1;k<=q;k++){
for(ll i=L;i<=R;i++)
for(ll j=i;j<=R;j++)
f[k&1][i][j]=f[~k&1][i][j]*(cnt[j-i+1]+cnt[i-1]+cnt[n-j]);
for(ll i=L;i<=R;i++){
ll buf=0;
for(ll j=R;j>=i;j--){
(f[k&1][i][j]+=buf)%=P;
(buf+=f[~k&1][i][j]*(n-j))%=P;
}
}
for(ll j=L;j<=R;j++){
ll buf=0;
for(ll i=L;i<=j;i++){
(f[k&1][i][j]+=buf)%=P;
(buf+=f[~k&1][i][j]*(i-1))%=P;
}
}
}
for(ll i=L;i<=R;i++){
ll buf=0;
for(ll j=R;j>=i;j--){
(buf+=f[q&1][i][j])%=P;
(ans[j][rk[x]]+=buf)%=P;
}
}
return;
}
signed main()
{
scanf("%lld%lld",&n,&q);
for(ll i=1;i<=n;i++)cnt[i]=i*(i+1)/2;
for(ll i=1;i<=n;i++){
scanf("%lld",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
ll m=unique(b+1,b+1+n)-b-1;
for(ll i=1;i<=n;i++)rk[i]=lower_bound(b+1,b+1+m,a[i])-b;
for(ll i=1;i<=n;i++){
ll L=i,R=i;
while(L>1&&a[L-1]<a[i])L--;
while(R<n&&a[R+1]<a[i])R++;
solve(i,L,R);
}
for(ll i=1;i<=n;i++){
ll sum=0;
for(ll j=1;j<=n;j++){
if(!ans[i][j]){continue;}
for(ll k=1;k<j;k++)
(ans[i][j]+=P-ans[i][k])%=P;
(sum+=ans[i][j]*b[j]%P)%=P;
}
printf("%lld ",sum);
}
return 0;
}

P3352-[ZJOI2016]线段树【dp】的更多相关文章

  1. bzoj4574:Zjoi2016线段树 dp

    传送门 题解传送门 //Achen #include<algorithm> #include<iostream> #include<cstring> #includ ...

  2. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  3. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  4. lightoj1085 线段树+dp

    //Accepted 7552 KB 844 ms //dp[i]=sum(dp[j])+1 j<i && a[j]<a[i] //可以用线段树求所用小于a[i]的dp[j ...

  5. [CF 474E] Pillars (线段树+dp)

    题目链接:http://codeforces.com/contest/474/problem/F 意思是给你两个数n和d,下面给你n座山的高度. 一个人任意选择一座山作为起始点,向右跳,但是只能跳到高 ...

  6. HDU-3872 Dragon Ball 线段树+DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3872 题意:有n个龙珠按顺序放在一列,每个龙珠有一个type和一个权值,要求你把这n个龙珠分成k个段, ...

  7. HDU4521+线段树+dp

    题意:在一个序列中找出最长的某个序列.找出的序列满足题中的条件. 关键:对于 第 i 个位置上的数,要知道与之相隔至少d的位置上的数的大小.可以利用线段树进行统计,查询.更新的时候利用dp的思想. / ...

  8. Codeforces Round #343 (Div. 2) D - Babaei and Birthday Cake 线段树+DP

    题意:做蛋糕,给出N个半径,和高的圆柱,要求后面的体积比前面大的可以堆在前一个的上面,求最大的体积和. 思路:首先离散化蛋糕体积,以蛋糕数量建树建树,每个节点维护最大值,也就是假如节点i放在最上层情况 ...

  9. Special Subsequence(离散化线段树+dp)

    Special Subsequence Time Limit: 5 Seconds      Memory Limit: 32768 KB There a sequence S with n inte ...

  10. hdu 4117 GRE Words (ac自动机 线段树 dp)

    参考:http://blog.csdn.net/no__stop/article/details/12287843 此题利用了ac自动机fail树的性质,fail指针建立为树,表示父节点是孩子节点的后 ...

随机推荐

  1. IDEA远程调试代码

    一.设置远程调式端口 点击Remote 设置名字和要部署的远程服务器IP地址和端口 二.将Jar包上传到远程服务器运行 启动命令 java -Xdebug -agentlib:jdwp=transpo ...

  2. 自定义Vue&Element组件,实现用户选择和显示

    在我们很多前端业务开发中,往往为了方便,都需要自定义一些用户组件,一个是减少单一页面的代码,提高维护效率:二个也是方便重用.本篇随笔介绍在任务管理操作中,使用自定义Vue&Element组件, ...

  3. .Net Core 集成 Redis

    首先安装RedisServer 安装教程可参照 http://www.redis.cn/download.html 或者 https://www.runoob.com/redis/redis-inst ...

  4. SpringBoot使用@Scheduled创建定时任务

    定时任务一般会存在中大型企业级项目中,为了减少服务器.数据库的压力往往会采用时间段性的去完成某些业务逻辑.比较常见的就是金融服务系统推送回调,一般支付系统订单在没有收到成功的回调返回内容时会持续性的回 ...

  5. Mybatis映射器(一)

    XML查询参数: parameterType:可以给出类别名,全名等. resultType:查询结果,可以为 int,float,map等不可以与resultMap同时使用. resultMap: ...

  6. jQuery中的样式(七):addClass()、removeClass()、toggleClass()、hasClass()、css()、width()、height()等

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  7. git推送文件到gitee

    注册gitee账号 设置姓名.个人空间地址 点击头像旁边的加号,新建仓库 安装git # 设置姓名和邮箱,姓名是注册gitee时设置的姓名,邮箱是注册gitee的邮箱 git config --glo ...

  8. Java实现小程序微信支付

    小程序支付流程交互图: 进入小程序,下单,请求下单支付,调用小程序登录API来获取Openid,生成商户订单 // pages/pay/pay.js var app = getApp(); Page( ...

  9. 挂载redhat镜像创建本地yum源

    上传镜像文件到/mnt文件夹下,或者上传到其他文件夹下 挂载镜像路径/mnt/cdrom 在mnt文件夹下创建cdrom文件夹 创建命令:mkdir  cdrom 挂载镜像命令:mount rhel- ...

  10. 三.Go微服务--令牌桶实现原理

    1. 前言 在上一篇文章 Go微服务: 令牌桶 当中简单的介绍了令牌桶实现的原理,然后利用 /x/time/rate 这个库 10 行代码写了一个基于 ip 的 gin 限流中间件,那这个功能是怎么实 ...