RE 30 求助
查看原帖
RE 30 求助
118196
zimujun楼主2021/2/13 17:24

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;
}
2021/2/13 17:24
加载中...