RT
开了 O2 还会 WA 第五个点
没建表达式树,直接在后缀表达式上求的,栈是数组模拟的,没用 STL
#include <bits/stdc++.h>
#define LL long long
#define v0 v0_
#define v1 v1_
#define v2 v2_
using namespace std;
namespace Basic {
template <typename Temp> inline void read(Temp & res) {
Temp fh = 1; res = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') fh = -1;
for(; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ '0');
res = res * fh;
}
}
using namespace Basic;
const int Maxn = 5e4 + 5;
const LL Mod = 1e9 + 7;
const int Maxt = (1 << 11);
const int Maxm = 11;
struct v {
LL ans[2];
v() {ans[0] = ans[1] = 0;}
};
v st[Maxn];
int tp1, tp2;
int stc[Maxn];
int sufc[Maxn], cnt, n, m;
char s[Maxn];
LL a[Maxn][10];
LL val[Maxt];
void work(int);
LL solve(int);
//void tr(int);
/*
int trans(char ch) {
if(ch == '<') return -1;
if(ch == '>') return -2;
if(ch == '?') return -3;
return -4;
}
void debug() {
printf("%d :", tp1);
for(int i = 1; i <= tp1; ++i) {
printf("(%lld, %lld) ", st[i].ans[1], st[i].ans[0]);
}
puts("");
}
*/
void prepare() {
read(n); read(m);
for(int i = 0; i < m; ++i) {
for(int j = 1; j <= n; ++j) {
read(a[j][i]);
}
}
scanf("%s", s + 1); int L = strlen(s + 1);
for(int i = 1; i <= L; ++i) {
//std::cout << s[i];
if(isdigit(s[i])) {
sufc[++cnt] = (s[i] ^ '0');
} else if(s[i] == '<' || s[i] == '>' || s[i] == '?') {
while(tp2 && stc[tp2] != '(') {
sufc[++cnt] = stc[tp2];
tp2--;
}
stc[++tp2] = s[i];
} else if(s[i] == '(') {
stc[++tp2] = '(';
} else if(s[i] == ')') {
while(tp2 && stc[tp2] != '(') {
sufc[++cnt] = stc[tp2];
tp2--;
}
tp2--;
}
}
while(tp2) {
sufc[++cnt] = stc[tp2]; tp2--;
}
for(int tS = 0; tS < (1 << m); ++tS) {
work(tS);
val[tS] = st[1].ans[1];
}
}
void work(int S) {
//tr(S);
tp1 = 0;
for(int i = 1; i <= cnt; ++i) {
if(sufc[i] >= 0 && sufc[i] <= 9) {
v v0;
v0.ans[(S >> sufc[i]) & 1] = 1;
st[++tp1] = v0;
} else {
v v1 = st[tp1]; tp1--;
v v2 = st[tp1];
v v0;
if(sufc[i] == '<') {
v0.ans[1] = v1.ans[1] * v2.ans[1] % Mod;
v0.ans[0] = ((v1.ans[0] * v2.ans[0] % Mod + v1.ans[0] * v2.ans[1] % Mod) % Mod + v1.ans[1] * v2.ans[0] % Mod) % Mod;
} else if(sufc[i] == '>') {
v0.ans[1] = ((v1.ans[1] * v2.ans[1] % Mod + v1.ans[0] * v2.ans[1] % Mod) % Mod + v1.ans[1] * v2.ans[0] % Mod) % Mod;
v0.ans[0] = v1.ans[0] * v2.ans[0];
} else if(sufc[i] == '?') {
//cout << 114514 << '\a' << '\n';
v0.ans[1] = ((v1.ans[1] * v2.ans[1] % Mod + v1.ans[0] * v2.ans[1] % Mod) % Mod + v1.ans[1] * v2.ans[0] % Mod) % Mod;
v0.ans[1] += v1.ans[1] * v2.ans[1] % Mod; v0.ans[1] %= Mod;
v0.ans[0] = ((v1.ans[0] * v2.ans[0] % Mod + v1.ans[0] * v2.ans[1] % Mod) % Mod + v1.ans[1] * v2.ans[0] % Mod) % Mod;
v0.ans[0] += v1.ans[0] * v2.ans[0] % Mod; v0.ans[0] %= Mod;
}
st[tp1] = v0;
//printf("Node %c ans : ( %lld / %lld )\n", sufc[i], v0.ans[1], v0.ans[0]);
}
//debug();
}
}
struct px {
LL data; int idx;
} p[11];
bool cmp(px A, px B) {
return A.data < B.data;
}
LL solve(int t) {
int tset[11];
for(int i = 0; i < m; ++i) {
p[i].data = a[t][i]; p[i].idx = i;
}
sort(p, p + m, cmp);
for(int i = m - 1; i >= 0; --i) {
tset[i] = tset[i + 1] | (1 << p[i].idx);
}
LL res = 0;
for(int i = 0; i < m; ++i) {
res += ((val[tset[i]] - val[tset[i + 1]]) % Mod + Mod) % Mod * p[i].data % Mod;
res %= Mod;
}
return res;
}
void print() {
LL answer = 0;
for(int i = 1; i <= n; ++i) {
answer += solve(i);
answer %= Mod;
}
printf("%lld", answer);
return;
}
/*
void tr(int t) {
for(int i = m - 1; i >= 0; --i) {
printf("%d", ((t >> i) & 1));
}
puts("");
}*/
int main() {
prepare();
/*std::cout << cnt << '\n';
for(int i = 1; i <= cnt; ++i) printf("%d ", sufc[i]); puts("");
for(int i = 0; i < (1 << m); ++i) {
tr(i);
printf(": %lld\n", val[i]);
}
*/
print();
return 0;
}