QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#863290 | #9222. Price Combo | forgive_ | WA | 0ms | 12116kb | C++14 | 4.5kb | 2025-01-19 15:35:19 | 2025-01-19 15:35:19 |
Judging History
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'