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

    System.Drawing 在linux使用时提示异常 The type initializer for 'Gdip' threw an exception 解决方案: yum install au ...

  2. Python中生成器的理解

    1.生成器的定义 在Python中一边循环一边计算的机制,称为生成器 2.为什么要有生成器 列表所有的数据都存在内存中,如果有海量的数据将非常耗内存 如:仅仅需要访问前面几个元素,那后面绝大多数元素占 ...

  3. Linux常用命令,查看树形结构、删除目录(文件夹)、创建文件、删除文件或目录、复制文件或目录(文件夹)、移动、查看文件内容、权限操作

    5.查看树结构(tree) 通常情况下系统未安装该命令,需要yum install -y tree安装 直接使⽤tree显示深度太多,⼀般会使⽤ -L选项⼿⼯设定⽬录深度 格式:tree -L n [ ...

  4. 【原创】Linux v4l2框架分析

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  5. 【UE4 C++】UKismetSystemLibrary 源代码

    // Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" # ...

  6. JAVA复习总体大纲

    1 java基础. [1].变量--- 数据类型 变量名=值; 数据类型: 1.基本数据类型. byte[1字节] short[2字节] int[4字节] long[8字节] float[4字节] d ...

  7. python标准库glob 递归目录下所有文件

    import glob for i in glob.glob(r'C:\Desktop\**',recursive=True): print(i) """ re:?*[0 ...

  8. Beta阶段第三次会议

    Beta阶段第三次会议 完成工作 姓名 工作 难度 完成度 ltx 1.掌握小程序代码和相关知识2.构思小程序游客模式 轻 90% xyq 1.修改场地表格信息2.对原页面活动申请场地部分进行修改 轻 ...

  9. mongodb的索引操作

    在mongodb中,当我们一个集合中的数据量非常大时,比如几百万条数据,如果不使用索引,对数据的查询就会进行全表扫描,这个时候查询的速度就会非常的慢,此时我们就需要为集合建立上索引,从而加快查询的速度 ...

  10. 在Vue前端项目中,附件展示的自定义组件开发

    在Vue前端界面中,自定义组件很重要,也很方便,我们一般是把一些通用的界面模块进行拆分,创建自己的自定义组件,这样操作可以大大降低页面的代码量,以及提高功能模块的开发效率,本篇随笔继续介绍在Vue&a ...