类似cf582E,先建出表达式树,然后树形dp+离散+min和max卷积的优化,复杂度为$o(nm|E|)$,无法通过

考虑我们仅关心于这$n$个数的大小关系,具体来说,假设给出的数组是$a_{i,j}$(其中$0\le i<m,1\le j\le n$),对于某一个$j$,将$a_{i,j}$从小到大排序后,依次是$a_{p_{i},j}$($0\le i<m$,$p_{i}$为$[0,m)$的一个排列)

暴力枚举$j$和$p_{i}$,接下来去统计答案不小于$a_{p_{i},j}$的方案数:

对于树形dp的状态上,我们仅需要记录小于$a_{p_{i},j}$和不小于$a_{p_{i},j}$的方案数,换言之是$o(1)$转移,但dp次数为$o(nm)$,因此总复杂度仍然是$o(nm|E|)$

但注意到,影响dp过程的只有对于每一个$i$,$[a_{i,j}\ge a_{p_{i},j}]$的值,不难发现至多$2^{m}$种,预处理出每一种值的结果,再枚举$j$和$p_{i}$求出是哪一种值即可

时间复杂度为$o(2^{m}|E|+nm)$,可以通过

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 #define N 50005
  4. 4 #define mod 1000000007
  5. 5 stack<int>st_op,st_num;
  6. 6 int V,n,m,p,ans,b[11][N],a[N],ls[N],rs[N],id[11],f[1<<10][N][2];
  7. 7 char s[N];
  8. 8 bool cmp(int x,int y){
  9. 9 return b[x][p]>b[y][p];
  10. 10 }
  11. 11 void merge(){
  12. 12 a[++V]=st_op.top();
  13. 13 st_op.pop();
  14. 14 rs[V]=st_num.top();
  15. 15 st_num.pop();
  16. 16 ls[V]=st_num.top();
  17. 17 st_num.pop();
  18. 18 st_num.push(V);
  19. 19 }
  20. 20 void dfs(int k,int p){
  21. 21 if ((!ls[k])&&(!rs[k])){
  22. 22 f[p][k][((p&(1<<a[k]))>0)]=1;
  23. 23 return;
  24. 24 }
  25. 25 dfs(ls[k],p);
  26. 26 dfs(rs[k],p);
  27. 27 int s=(1LL*f[p][ls[k]][0]*f[p][rs[k]][1]+1LL*f[p][ls[k]][1]*f[p][rs[k]][0])%mod;
  28. 28 if (a[k]==0){
  29. 29 f[p][k][0]=(1LL*f[p][ls[k]][0]*f[p][rs[k]][0]+s)%mod;
  30. 30 f[p][k][1]=1LL*f[p][ls[k]][1]*f[p][rs[k]][1]%mod;
  31. 31 }
  32. 32 if (a[k]==1){
  33. 33 f[p][k][0]=1LL*f[p][ls[k]][0]*f[p][rs[k]][0]%mod;
  34. 34 f[p][k][1]=(1LL*f[p][ls[k]][1]*f[p][rs[k]][1]+s)%mod;
  35. 35 }
  36. 36 if (a[k]==2){
  37. 37 f[p][k][0]=(2LL*f[p][ls[k]][0]*f[p][rs[k]][0]+s)%mod;
  38. 38 f[p][k][1]=(2LL*f[p][ls[k]][1]*f[p][rs[k]][1]+s)%mod;
  39. 39 }
  40. 40 }
  41. 41 int main(){
  42. 42 scanf("%d%d",&n,&m);
  43. 43 for(int i=0;i<m;i++)
  44. 44 for(int j=1;j<=n;j++)scanf("%d",&b[i][j]);
  45. 45 scanf("%s",s);
  46. 46 int l=strlen(s),flag=0;
  47. 47 for(int i=0;i<l;i++)
  48. 48 if (('0'<=s[i])&&(s[i]<='9')){
  49. 49 a[++V]=s[i]-'0';
  50. 50 st_num.push(V);
  51. 51 if ((!st_op.empty())&&(st_op.top()!=-1))merge();
  52. 52 }
  53. 53 else{
  54. 54 if (s[i]=='(')st_op.push(-1);
  55. 55 if (s[i]=='<')st_op.push(0);
  56. 56 if (s[i]=='>')st_op.push(1);
  57. 57 if (s[i]=='?'){
  58. 58 st_op.push(2);
  59. 59 flag=1;
  60. 60 }
  61. 61 if (s[i]==')'){
  62. 62 st_op.pop();
  63. 63 if ((!st_op.empty())&&(st_op.top()!=-1))merge();
  64. 64 }
  65. 65 }
  66. 66 while (!st_op.empty())merge();
  67. 67 for(int i=0;i<(1<<m);i++)dfs(V,i);
  68. 68 for(int i=1;i<=n;i++){
  69. 69 for(int j=0;j<m;j++)id[j]=j;
  70. 70 p=i;
  71. 71 sort(id,id+m,cmp);
  72. 72 id[m]=m;
  73. 73 int s=0;
  74. 74 for(int j=0;j<m;j++){
  75. 75 s|=(1<<id[j]);
  76. 76 ans=(ans+1LL*f[s][V][1]*(b[id[j]][i]-b[id[j+1]][i]))%mod;
  77. 77 }
  78. 78 }
  79. 79 printf("%d",ans);
  80. 80 return 0;
  81. 81 }

[loj3463]表达式求值的更多相关文章

  1. 表达式求值(noip2015等价表达式)

    题目大意 给一个含字母a的表达式,求n个选项中表达式跟一开始那个等价的有哪些 做法 模拟一个多项式显然难以实现那么我们高兴的找一些素数代入表达式,再随便找一个素数做模表达式求值优先级表 - ( ) + ...

  2. 用Python3实现表达式求值

    一.题目描述 请用 python3 编写一个计算器的控制台程序,支持加减乘除.乘方.括号.小数点,运算符优先级为括号>乘方>乘除>加减,同级别运算按照从左向右的顺序计算. 二.输入描 ...

  3. 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

    一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...

  4. nyoj305_表达式求值

    表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min ...

  5. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

  6. 数据结构--栈的应用(表达式求值 nyoj 35)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35 题目: 表达式求值 时间限制:3000 ms | 内存限制:65535 KB描述 AC ...

  7. NOIP2013普及组 T2 表达式求值

    OJ地址:洛谷P1981 CODEVS 3292 正常写法是用栈 #include<iostream> #include<algorithm> #include<cmat ...

  8. HNU 12817 Shipura(表达式求值)

    题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=12817 解题报告:定义两种运算符号,一种是>>,就 ...

  9. NOIP201302表达式求值

    NOIP201302表达式求值 题目描述 Description 给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值. 输入描述 Input Description 输入仅有一行,为需要你计 ...

随机推荐

  1. C语言实现简易计算器(可作加减乘除)

    C语言实现简易计算器(加减乘除) 计算器作为课设项目,已完成答辩,先将代码和思路(注释中)上传一篇博客 已增添.修改.整理至无错且可正常运行 虽使用了栈,但初学者可在初步了解栈和结构语法后理解代码 # ...

  2. 【UE4 C++ 基础知识】<8> Delegate 委托

    概念 定义 UE4中的delegate(委托)常用于解耦不同对象之间的关联:委托的触发者不与监听者有直接关联,两者通过委托对象间接地建立联系. 监听者通过将响应函数绑定到委托上,使得委托触发时立即收到 ...

  3. [no code][scrum meeting] Beta 7

    $( "#cnblogs_post_body" ).catalog() 例会时间:5月21日15:30,主持者:彭毛小民 下次例会时间:5月22日15:30,主持者:赵涛 昨日为5 ...

  4. seata序列化日期类型出错

    一.背景 最近在整合seata的过程中,发现如果业务表中存在 datetime 的数据类型,那么在分布式事务中,修改这个字段的值时,会出现如下错误.此处提供2种解决方案. com.fasterxml. ...

  5. Spring Security Jwt Token 自动刷新

    token的自动刷新 一.功能需求 二.功能分析 1.token 的生成 2.token 的自动延长 3.系统资源的保护 4.用户如何传递 token 三.实现思路 1.生成 token 和 refr ...

  6. 五分钟搞懂spring-cloud-square

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 初识spring-cloud-square 2021年 ...

  7. stm32知识学习的先后顺序

    这里大概的罗列了一些学习STM32的内容,以及学习顺序.如果是新手的话,建议边看中文手册和学习视频;如果是已经入门的,个人建议自己做一个项目,不论项目大小,当然里面会涉及到自己已经学习过的,或者是自己 ...

  8. SpringCloud微服务实战——搭建企业级开发框架(九):使用Nacos发现、配置和管理微服务

    Nacos是一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台,Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置 ...

  9. JAVA笔记10__Math类、Random类、Arrays类/日期操作类/对象比较器/对象的克隆/二叉树

    /** * Math类.Random类.Arrays类:具体查JAVA手册...... */ public class Main { public static void main(String[] ...

  10. 『学了就忘』Linux基础命令 — 24、文件基本权限的相关命令

    目录 1.chmod命令 2.权限模式 (1)用户身份. (2)赋予方式. (3)权限. 3.数字权限 4.文件常用权限 5.chown命令 6.chgrp命令 7.总结 常用基本权限操作命令: ch ...