QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#863290#9222. Price Comboforgive_WA 0ms12116kbC++144.5kb2025-01-19 15:35:192025-01-19 15:35:19

Judging History

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

  • [2025-01-19 15:35:19]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:12116kb
  • [2025-01-19 15:35:19]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std ;

typedef long long LL ;
const int N = 2e5+10 ;
const LL inf = 1e14 ;
// 神题
// 一种类型题:线段树节点维护矩阵,转移用区间乘矩阵来实现 
// 先观察,得到 n^2 做法
// 考虑扫描线,线段树优化 dp
// 进一步观察:dp 值一定是两段区间合并得到的,这种东西可以在线段树 pushup 时维护 
// 对 Min+ 矩阵的理解 

int n ;
struct nn
{
	int x , y , pos ;
}p[N] ;
bool cmp1( nn a , nn b ) 
{
	return a.y>b.y||(a.y==b.y&&a.x>b.x) ;
}
bool cmp2( nn a , nn b )
{
	return a.x>b.x||(a.x==b.x&&a.y>b.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 ;
				for(int k = 0 ; k < 4 ; k ++ ) {
					C.mat[i][j] = min( C.mat[i][j] , A.mat[i][k]+B.mat[k][j] ) ;
				}
			}
		}
		return C ;
	}
	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] = min( A.mat[i][j] , B.mat[i][j] ) ;
			}
		}
		return C ;
	}
	void Init() {
		for(int i = 0 ; i < 4 ; i ++ ) {
			for(int j = 0 ; j < 4 ; j ++ ) mat[i][j] = inf ;
		}
	}
	LL val() {
		return min({mat[0][0],mat[1][0],mat[2][0],mat[3][0]}) ;
	}
	void db() {
		printf("db:\n") ;
		for(int i = 0 ; i < 4 ; i ++ ) {
			for(int j = 0 ; j < 4 ; j ++ ) {
				if( mat[i][j]<inf ) printf("%lld " , mat[i][j] ) ;
				else printf("inf ") ;
			}
			printf("\n") ;
		}
		printf("\n") ;
	}
} F[N<<2] , G[N<<2] , T[N<<2] , I ;
void discrete()
{
	p[++n] = {1000000000+1,1000000000+1,0} ;
	p[++n] = {0,0,0} ;
	sort( p+1 , p+n+1 , cmp1 ) ;
	for(int i = 1 ; i <= n ; i ++ ) p[i].pos = i ; //对应的线段树节点 
	sort( p+1 , p+n+1 , cmp2 ) ;
	I.Init() ;
	I.mat[0][0] = I.mat[1][1] = I.mat[2][2] = I.mat[3][3] = 0 ;
}
struct Segtree
{
	int l , r ;
	bool tag ;
}t[N<<2] ;
inline void update( int p )
{
	G[p] = G[p<<1]*G[p<<1|1] ;
	F[p] = F[p<<1]*G[p<<1|1] + F[p<<1|1] ;
}
void build( int p , int l , int r )
{
	t[p].l = l , t[p].r = r ;
	if( l == r ) {
		F[p].Init() ; G[p] = I ;
		return ;
	}
	int mid = (l+r)>>1 ;
	build(p<<1,l,mid) ; build(p<<1|1,mid+1,r) ;
	update(p) ;
}
matrix tmp , tx ;
inline void Upd( int p , const matrix A )
{
	F[p] = F[p]*A ;
	if( !t[p].tag ) {
		t[p].tag = 1 , T[p] = A ;
	}
	else {
		T[p] = T[p]*A ;
	}
}
inline void spread( int p )
{
	if( t[p].tag ) {
		Upd(p<<1,T[p]) ; Upd(p<<1|1,T[p]) ;
		t[p].tag = 0 ;
	}
}
void modify( int p , int x )
{
	if( t[p].l==t[p].r ) {
		F[p] = F[p]+tmp ;
		return ;
	}
	spread(p) ;
	int mid = (t[p].l+t[p].r)>>1 ;
	if( x <= mid ) modify(p<<1,x) ;
	else modify(p<<1|1,x) ;
	update(p) ;
}
void query( int p , int l , int r )
{
	if( l <= t[p].l && t[p].r <= r ) {
		tmp = tmp+F[p] ;
		return ;
	}
	spread(p) ;
	int mid = (t[p].l+t[p].r)>>1 ;
	if( l <= mid ) query(p<<1,l,r) ;
	if( r > mid ) query(p<<1|1,l,r) ;
}
void change( int p , int l , int r ) // F*=tx
{
	if( l <= t[p].l && t[p].r <= r ) {
		Upd(p,tx) ;
		return ;  
	} 
	spread(p) ;
	int mid = (t[p].l+t[p].r)>>1 ;
	if( l <= mid ) change(p<<1,l,r) ;
	if( r > mid ) change(p<<1|1,l,r) ;
	update(p) ;
}
void modify1( int p , int x ) // G*=tx 
{
	if( t[p].l == t[p].r ) {
		G[p] = G[p]*tx ;
//		printf("At [%d,%d] :\n" , t[p].l , t[p].r ) ;
//		G[p].db() ;
		return ;
	}
	spread(p) ;
	int mid = (t[p].l+t[p].r)>>1 ;
	if( x <= mid ) modify1(p<<1,x) ;
	else modify1(p<<1|1,x) ;
	update(p) ;
}

int main()
{
	scanf("%d" , &n ) ;
	for(int i = 1 ; i <= n ; i ++ ) scanf("%d" , &p[i].x ) ;
	for(int i = 1 ; i <= n ; i ++ ) scanf("%d" , &p[i].y ) ;
	discrete() ;
	build(1,1,n) ;
	tmp = I ;
	modify(1,p[1].pos) ;
	
//	printf("add (%d,%d) , v=%d\n" , p[1].x,p[1].y , 0 ) ;
//	tmp.Init() ; query(1,1,2) ; tmp.db() ;
	
	for(int i = 2 ; i <= n ; i ++ ) {
		tmp.Init() ; query(1,1,p[i].pos) ;
//		printf("add (%d,%d) \n" , p[i].x,p[i].y ) ;
//		tmp.db() ;
		if( i == n ) {
			printf("%lld\n" , tmp.val() ) ;
			return 0 ;
		}
		modify(1,p[i].pos) ;
		tx.Init() ;
		tx.mat[0][2] = 0 , tx.mat[1][3] = 0 , tx.mat[2][0] = p[i].x , tx.mat[3][1] = p[i].x ;
		change(1,p[i].pos,n) ;
		
//		printf(" change [%d,%d]\n" , p[i].pos , n ) ;
//		tmp.Init() ; query(1,p[i].pos,p[i].pos) ;
//		tmp.db() ; 
		
		tx.Init() ;
		tx.mat[0][1] = 0 , tx.mat[1][0] = p[i].y , tx.mat[2][3] = 0 , tx.mat[3][2] = p[i].y ;
		modify1(1,p[i].pos) ;
	}
	return 0 ; 
}
/*
3
3 2 3
2 3 5
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 12116kb

input:

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

output:

32

result:

wrong answer 1st lines differ - expected: '131', found: '32'