QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#864134#9222. Price CombochangziliangRE 0ms0kbC++2010.2kb2025-01-20 10:54:302025-01-20 10:54:31

Judging History

你现在查看的是最新测评结果

  • [2025-01-20 10:54:31]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2025-01-20 10:54:30]
  • 提交

answer

// b, a 的转移都写成矩阵的形式, 这个感觉很厉害 
#include<bits/stdc++.h>
#define pb emplace_back
#define MP make_pair
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int N = 2e5 + 10;
inline LL Min(LL x, LL y) {return x <= y ? x : y;}
struct matrix {
	LL mat[4][4];
	friend matrix operator * (matrix a, matrix b) {
		matrix c; 
		for(int i = 0; i < 4; i ++ )
		    for(int j = 0; j < 4; j ++ ) 
		        c.mat[i][j] = INF;
		c.mat[0][0] = min(c.mat[0][0], a.mat[0][0] + b.mat[0][0]);
		c.mat[0][0] = min(c.mat[0][0], a.mat[0][1] + b.mat[1][0]);
		c.mat[0][0] = min(c.mat[0][0], a.mat[0][2] + b.mat[2][0]);
		c.mat[0][0] = min(c.mat[0][0], a.mat[0][3] + b.mat[3][0]);
		c.mat[0][1] = min(c.mat[0][1], a.mat[0][0] + b.mat[0][1]);
		c.mat[0][1] = min(c.mat[0][1], a.mat[0][1] + b.mat[1][1]);
		c.mat[0][1] = min(c.mat[0][1], a.mat[0][2] + b.mat[2][1]);
		c.mat[0][1] = min(c.mat[0][1], a.mat[0][3] + b.mat[3][1]);
		c.mat[0][2] = min(c.mat[0][2], a.mat[0][0] + b.mat[0][2]);
		c.mat[0][2] = min(c.mat[0][2], a.mat[0][1] + b.mat[1][2]);
		c.mat[0][2] = min(c.mat[0][2], a.mat[0][2] + b.mat[2][2]);
		c.mat[0][2] = min(c.mat[0][2], a.mat[0][3] + b.mat[3][2]);
		c.mat[0][3] = min(c.mat[0][3], a.mat[0][0] + b.mat[0][3]);
		c.mat[0][3] = min(c.mat[0][3], a.mat[0][1] + b.mat[1][3]);
		c.mat[0][3] = min(c.mat[0][3], a.mat[0][2] + b.mat[2][3]);
		c.mat[0][3] = min(c.mat[0][3], a.mat[0][3] + b.mat[3][3]);
		
		c.mat[1][0] = min(c.mat[1][0], a.mat[1][0] + b.mat[0][0]);
		c.mat[1][0] = min(c.mat[1][0], a.mat[1][1] + b.mat[1][0]);
		c.mat[1][0] = min(c.mat[1][0], a.mat[1][2] + b.mat[2][0]);
		c.mat[1][0] = min(c.mat[1][0], a.mat[1][3] + b.mat[3][0]);
		c.mat[1][1] = min(c.mat[1][1], a.mat[1][0] + b.mat[0][1]);
		c.mat[1][1] = min(c.mat[1][1], a.mat[1][1] + b.mat[1][1]);
		c.mat[1][1] = min(c.mat[1][1], a.mat[1][2] + b.mat[2][1]);
		c.mat[1][1] = min(c.mat[1][1], a.mat[1][3] + b.mat[3][1]);
		c.mat[1][2] = min(c.mat[1][2], a.mat[1][0] + b.mat[0][2]);
		c.mat[1][2] = min(c.mat[1][2], a.mat[1][1] + b.mat[1][2]);
		c.mat[1][2] = min(c.mat[1][2], a.mat[1][2] + b.mat[2][2]);
		c.mat[1][2] = min(c.mat[1][2], a.mat[1][3] + b.mat[3][2]);
		c.mat[1][3] = min(c.mat[1][3], a.mat[1][0] + b.mat[0][3]);
		c.mat[1][3] = min(c.mat[1][3], a.mat[1][1] + b.mat[1][3]);
		c.mat[1][3] = min(c.mat[1][3], a.mat[1][2] + b.mat[2][3]);
		c.mat[1][3] = min(c.mat[1][3], a.mat[1][3] + b.mat[3][3]);

		c.mat[2][0] = min(c.mat[2][0], a.mat[2][0] + b.mat[0][0]);
		c.mat[2][0] = min(c.mat[2][0], a.mat[2][1] + b.mat[1][0]);
		c.mat[2][0] = min(c.mat[2][0], a.mat[2][2] + b.mat[2][0]);
		c.mat[2][0] = min(c.mat[2][0], a.mat[2][3] + b.mat[3][0]);
		c.mat[2][1] = min(c.mat[2][1], a.mat[2][0] + b.mat[0][1]);
		c.mat[2][1] = min(c.mat[2][1], a.mat[2][1] + b.mat[1][1]);
		c.mat[2][1] = min(c.mat[2][1], a.mat[2][2] + b.mat[2][1]);
		c.mat[2][1] = min(c.mat[2][1], a.mat[2][3] + b.mat[3][1]);
		c.mat[2][2] = min(c.mat[2][2], a.mat[2][0] + b.mat[0][2]);
		c.mat[2][2] = min(c.mat[2][2], a.mat[2][1] + b.mat[1][2]);
		c.mat[2][2] = min(c.mat[2][2], a.mat[2][2] + b.mat[2][2]);
		c.mat[2][2] = min(c.mat[2][2], a.mat[2][3] + b.mat[3][2]);
		c.mat[2][3] = min(c.mat[2][3], a.mat[2][0] + b.mat[0][3]);
		c.mat[2][3] = min(c.mat[2][3], a.mat[2][1] + b.mat[1][3]);
		c.mat[2][3] = min(c.mat[2][3], a.mat[2][2] + b.mat[2][3]);
		c.mat[2][3] = min(c.mat[2][3], a.mat[2][3] + b.mat[3][3]);
		
		c.mat[3][0] = min(c.mat[3][0], a.mat[3][0] + b.mat[0][0]);
		c.mat[3][0] = min(c.mat[3][0], a.mat[3][1] + b.mat[1][0]);
		c.mat[3][0] = min(c.mat[3][0], a.mat[3][2] + b.mat[2][0]);
		c.mat[3][0] = min(c.mat[3][0], a.mat[3][3] + b.mat[3][0]);
		c.mat[3][1] = min(c.mat[3][1], a.mat[3][0] + b.mat[0][1]);
		c.mat[3][1] = min(c.mat[3][1], a.mat[3][1] + b.mat[1][1]);
		c.mat[3][1] = min(c.mat[3][1], a.mat[3][2] + b.mat[2][1]);
		c.mat[3][1] = min(c.mat[3][1], a.mat[3][3] + b.mat[3][1]);
		c.mat[3][2] = min(c.mat[3][2], a.mat[3][0] + b.mat[0][2]);
		c.mat[3][2] = min(c.mat[3][2], a.mat[3][1] + b.mat[1][2]);
		c.mat[3][2] = min(c.mat[3][2], a.mat[3][2] + b.mat[2][2]);
		c.mat[3][2] = min(c.mat[3][2], a.mat[3][3] + b.mat[3][2]);
		c.mat[3][3] = min(c.mat[3][3], a.mat[3][0] + b.mat[0][3]);
		c.mat[3][3] = min(c.mat[3][3], a.mat[3][1] + b.mat[1][3]);
		c.mat[3][3] = min(c.mat[3][3], a.mat[3][2] + b.mat[2][3]);
		c.mat[3][3] = min(c.mat[3][3], a.mat[3][3] + b.mat[3][3]);
		return c;
  	}
  	friend bool operator != (matrix a, matrix b) {
  		for(int i = 0; i < 4; i ++ ) 
  		    for(int j = 0; j < 4; j ++ ) 
  		        if(a.mat[i][j] != b.mat[i][j]) return 1;
  		return 0;
	}
} I, T;
typedef pair< int, matrix > PII;
matrix Min(matrix a, matrix b) {
	matrix c;
	for(int i = 0; i < 4; i ++ ) 
	    for(int j = 0; j < 4; j ++ ) 
	        c.mat[i][j] = min(a.mat[i][j], b.mat[i][j]);
	return c;
}
struct SegmentTree {
	int l, r; 
	matrix tag, mt, mb; // tag 是懒标记, b 的转移矩阵, a 的可以最后乘 
	#define l(x) t[x].l
	#define r(x) t[x].r
	#define tag(x) t[x].tag
	#define mt(x) t[x].mt
	#define mb(x) t[x].mb
}t[N * 4];
int n, a[N], b[N];
int va[N], vb[N], ta, tb;
int idx[N], up[N]; // 每个上面有多少个 
int cnt[N];
matrix geta(int c, int v) {
	matrix res = T;
    if(c & 1) {
        for(int i = 0; i <= 1; i ++ ) 
        	for(int j = 0; j <= 1; j ++ ) 
        		if(i == 0) res.mat[i * 2 + j][(i ^ 1) * 2 + j] = 1LL * (c + 1) / 2 * v;
        		else res.mat[i * 2 + j][(i ^ 1) * 2 + j] = 1LL * (c - 1) / 2 * v;
	}	
	else {
		for(int i = 0; i < 4; i ++ ) res.mat[i][i] = 1LL * (c / 2) * v;
	}
	return res;
}
matrix getb(int c, int v) {
	matrix res = T;
    if(c & 1) {
        for(int i = 0; i <= 1; i ++ ) 
        	for(int j = 0; j <= 1; j ++ ) 
        		if(j == 0) res.mat[i * 2 + j][i * 2 + (j ^ 1)] = 1LL * (c + 1) / 2 * v;
        		else res.mat[i * 2 + j][i * 2 + (j ^ 1)] = 1LL * (c - 1) / 2 * v;
	}	
	else {
		for(int i = 0; i < 4; i ++ ) res.mat[i][i] = 1LL * (c / 2) * v;
	}
	return res;
}
bool cmp(int x, int y) {
	return (a[x] < a[y]) || (a[x] == a[y] && b[x] > b[y]);
}
void update(int p) {
	mt(p) = Min(mt(p << 1 | 1) * mb(p << 1), mt(p << 1));
	mb(p) = mb(p << 1 | 1) * mb(p << 1);
}
void spread(int p) {
	if(tag(p) != I) {
		mt(p << 1) = mt(p << 1) * tag(p); mt(p << 1 | 1) = mt(p << 1 | 1) * tag(p);
		tag(p << 1) = tag(p << 1) * tag(p); tag(p << 1 | 1) = tag(p << 1 | 1) * tag(p);
		tag(p) = I;
	} 
}
void build(int p, int l, int r) {
	l(p) = l, r(p) = r;
	tag(p) = I, mb(p) = I;
	if(l == r) {
		mt(p) = T;
		return ;
	}
	int mid = (l + r >> 1);
	build(p << 1, l, mid);
	build(p << 1 | 1, mid + 1, r);
	update(p);
}
void ins(int p, int pos, matrix w) {
	if(l(p) == r(p)) {
		mt(p) = Min(mt(p), w);
		return ;
	}
	spread(p);
	int mid = (l(p) + r(p) >> 1);
	if(pos <= mid) ins(p << 1, pos, w);
	else ins(p << 1 | 1, pos, w);
	update(p);
}
void Change_a(int p, int l, int r, matrix w) {
	if(!(mt(p) != T)) return ;
	if(l <= l(p) && r >= r(p)) {
		mt(p) = mt(p) * w; 
		tag(p) = tag(p) * w;
		return ;
	}
	spread(p);
	int mid = (l(p) + r(p) >> 1);
	if(l <= mid) Change_a(p << 1, l, r, w);
	if(r > mid) Change_a(p << 1 | 1, l, r, w);
	update(p);
} 
void Change_b(int p, int pos) {
	if(l(p) == r(p)) {
		mb(p) = getb(cnt[pos], vb[pos]);
		return ;
	}
	int mid = (l(p) + r(p) >> 1);
	if(pos <= mid) Change_b(p << 1, pos);
	else Change_b(p << 1 | 1, pos);
	update(p);
}
matrix ret, sb;
void ask(int p, int l, int r) {
	if(l <= l(p) && r >= r(p)) {ret = Min(ret, mt(p) * sb); sb = mb(p) * sb; return ;}
	spread(p);
	int mid = (l(p) + r(p) >> 1);
	if(l <= mid) ask(p << 1, l, r);
	if(r > mid) ask(p << 1 | 1, l, r);
}
matrix Ask_mt(int p, int pos) {
	if(l(p) == r(p)) return mt(p);
	spread(p);
	int mid = (l(p) + r(p) >> 1);
	if(pos <= mid) return Ask_mt(p << 1, pos);
	else return Ask_mt(p << 1 | 1, pos);
}
vector< PII > vec;
int main() {
	freopen("data.in", "r", stdin);
	freopen("data.out", "w", stdout);
	scanf("%d", &n);
	for(int i = 0; i <= n + 1; i ++ ) {
		if(i == 0) a[i] = 0;
		else if(i == n + 1) a[i] = 1e9 + 10;
		else scanf("%d", &a[i]);
		va[++ ta] = a[i];
	}
	for(int i = 0; i <= n + 1; i ++ ) {
		if(i == 0) b[i] = 0;
		else if(i == n + 1) b[i] = 1e9 + 10;
		else scanf("%d", &b[i]);
		vb[++ tb] = b[i];
	}
	sort(va + 1, va + ta + 1);
	ta = unique(va + 1, va + ta + 1) - (va + 1);
	sort(vb + 1, vb + tb + 1);
	tb = unique(vb + 1, vb + tb + 1) - (vb + 1);
	for(int i = 0; i <= n + 1; i ++ ) {
		a[i] = lower_bound(va + 1, va + ta + 1, a[i]) - (va);
		b[i] = lower_bound(vb + 1, vb + tb + 1, b[i]) - (vb);
	} // 离散化 
	for(int i = 0; i <= n + 1; i ++ ) idx[i] = i;
	sort(idx, idx + n + 2, cmp);
	
//	for(int i = 0; i <= n + 1; i ++ ) {
//		printf("%d %d %d\n", idx[i], a[idx[i]], b[idx[i]]);
//	}
	for(int i = 0; i <= n + 1; i ++ ) {
		if(a[idx[i]] != a[idx[i - 1]]) up[idx[i]] = 1;
		else up[idx[i]] = up[idx[i - 1]] + 1;
	}
	up[idx[0]] = 0;
	for(int i = 0; i < 4; i ++ ) 
	    for(int j = 0; j < 4; j ++ ) {
	        I.mat[i][j] = (i == j ? 0 : INF);
	    	T.mat[i][j] = INF;
		}
	build(1, 1, tb);
	for(int i = n + 1; i >= 0; i -- ) { // 倒着转移 
	  //  double st = clock();
	    int o = idx[i]; // 首先可以在这个 b[o] 的下面乘上一个 a 的转移向量 
	    if(a[idx[i]] != a[idx[i + 1]]) { // 换列的时候插入 
	    	for(auto v : vec) {
	    		ins(1, v.first, v.second);
			}
			vec.clear();
		}
		if(i <= n) {
		    Change_a(1, 1, b[o], geta(1, va[a[o]])); // 乘上这样一个矩阵,表示a集合多了一个数
			ret = T; sb = getb(cnt[b[o]], vb[b[o]]); 
			ask(1, b[o] + 1, tb); // 状态 * b 矩阵, 表示这个状态多了若干个 b 矩阵 
			ret = ret * geta(up[o], va[a[o]]);
			vec.pb(MP(b[o], ret));
			cnt[b[o]] ++;
			Change_b(1, b[o]); // 半在线, 改变 b 矩阵 
		}
		else { // 第一个 
			matrix tmp;
			for(int j = 0; j < 4; j ++ ) 
			    for(int k = 0; k < 4; k ++ ) {
			        if(j == 0 && k == 0) tmp.mat[j][k] = 0;
			    	else tmp.mat[j][k] = INF;
				}
            ins(1, b[o], tmp);
		}
	}
	matrix ret = vec[0].second;
	LL res = INF;
	for(int i = 0; i < 4; i ++ ) res = min(res, ret.mat[0][i]);
	printf("%lld\n", res);
	return 0;
}
/*
7
7 9 1 2 15 20 17 
12 14 18 7 4 19 10 

*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Dangerous Syscalls

input:

7
10 12 19 99 10 8 49
9 14 15 199 11 7 19

output:


result: