查税( 斜率优化&单调队列维护凸包 &分块 )
来源:互联网 发布:福建厦门广电网络 编辑:程序博客网 时间:2024/06/18 03:29
id3167
有n个办公室,m个操作,依次读入
type
如果type为1 , 接着读入 T K Z S , 表示一个公司于T时刻进驻K办公室,每天盈利为Z,其一开始有S元。若K位置本有别的公司,别的公司会被覆盖。
如果type为2 , 接着读入T A B 表示于T时刻,你要找出区间[A,B]内,最有钱的公司的钱数。(关于钱的值都可以为负)
若AB内无公司输出“nema”
每次操作T不相同。
显然,题意是要插入很多条直线y=kx+b,在线询问当x为某值是,区间上的直线们的最大值。
如果写暴力的话,查询O(N),插入O(1),考虑分块平均平均调剂调剂,把它们都搞成O(
我们把直线的参数k,b看做是二维平面BOK上的点。每个块互不影响地插入块上的直线 。
我们可以发现本题有个单调性,若某两条直线
插入的话,删除原来在那个位置的直线,重构整个块(好暴力啊)
以k为关键字升序排序块内元素。构造一个单调队列,从队尾加元素,其实根据上述单调性,我们发现是在一个二维平面上维护一个上凸壳。叉积维护凸性即可。
对于询问,若一个块没有被询问区间包含,暴力地扫出答案。其余被包含的块可以维护单调队列队首元素,保证队首最优(判断条件即
问题得以解决
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std ;#define N 100010#define SRN 351typedef long long ll ;int n , m , i , j , k , T ;const int inf = 210000000 ;struct point { ll k , b , ps ;}a[N] ;ll operator *( point a , point b ) { return a.k * b.b - b.k * a.b ;}point operator -( point a , point b ) { point ret ; ret.ps = 0 , ret.k = a.k-b.k , ret.b = a.b-b.b ; return ret ;}struct Block { int q[SRN] ; // According to Sorted Postition int st , en , l , r ;}B[SRN] ;point tmp[N] ;struct FOR_BRUTE { ll k , b ;}Y[N] ;ll min( ll a , ll b ) { return a < b ? a : b ;}ll max( ll a , ll b ) { return a > b ? a : b ;}int main() { scanf("%d%d",&n,&m ) ; int sqt = sqrt( n ) ; int l , r ; for( i=1 , l = 1 , r =sqt ; l<=n ; l = r + 1 , r = ( r+sqt>n ? n : r+sqt ) , i++ ) { B[i].st = l , B[i].en = r ; B[i].l = 1 , B[i].r = 0 ; T = i ; } for( i=1 ; i<=n ; i++ ) a[i].ps = i , a[i].k = inf , Y[i].k = inf ; while( m-- ) { int typ ; scanf("%d",&typ ) ; if( typ==1 ) { ll x , ps , s , k , b ; scanf("%lld%lld%lld%lld",&x,&ps,&k,&s ) ; b = -k * x + s ; Y[ps].k = k , Y[ps].b = b ; int l ; bool proce = 0 ; for( i=1 ; i<=T ; i++ ) if( B[i].st<=ps && B[i].en>=ps ) break ; for( j=B[i].st , l = B[i].st ; l<=B[i].en ; l++ ) { if( a[j].ps==ps ) j++ ; if( proce==0 && ( k<a[j].k || j>B[i].en ) ) { tmp[l].k = k , tmp[l].b = b ; tmp[l].ps = ps ; proce = 1 ; } else tmp[l] = a[j++] ; } for( j=B[i].st ; j<=B[i].en ; j++ ) a[j] = tmp[j] ; int r = 1 ; l = 1 ; B[i].q[1] = B[i].st ; B[i].q[2] = B[i].st + 1 ; if( a[ B[i].q[2] ].k!=inf && B[i].st + 1 <= B[i].en ) { r = 2 ; for( j=B[i].st+2 ; a[j].k!=inf && j<=B[i].en ; j++ ) { while( l<=r-1 && ( a[j]-a[ B[i].q[r-1] ] ) * ( a[ B[i].q[r] ] - a[ B[i].q[r-1] ] ) < 0 ) r-- ; B[i].q[++r] = j ; } } B[i].l = l , B[i].r = r ; } else { ll x , aa , b , ans=-100000000000000ll ; scanf("%lld%lld%lld",&x,&aa,&b ) ; if( b<aa ) swap( aa , b ) ; for( i=1 ; i<=T ; i++ ) { if( b<B[i].st || aa>B[i].en ) continue ; // u->v if( aa<=B[i].st && b>=B[i].en ) { int l = B[i].l , r = B[i].r ; if( l>r ) continue ; while( l<=r-1 && a[ B[i].q[l] ].k * x + a[ B[i].q[l] ].b < a[ B[i].q[l+1] ].k * x + a[ B[i].q[l+1] ].b ) l++ ; ans = max( a[ B[i].q[l] ].k * x + a[ B[i].q[l] ].b , ans ) ; B[i].l = l , B[i].r = r ; } else { int u = max( B[i].st ,aa ) , v = min( B[i].en , b ) ; for( j=u ; j<=v ; j++ ) if( Y[j].k!=inf ) ans = max( Y[j].k * x + Y[j].b , ans ) ; } } if( ans==-100000000000000ll ) puts("nema" ) ; else printf("%lld\n",ans ) ; } }}
0 0
- 查税( 斜率优化&单调队列维护凸包 &分块 )
- ##单调队列、斜率优化##
- 生产汽车(单调队列+斜率优化)
- 斜率优化+单调队列优化DP
- 斜率优化+单调队列优化DP<转>
- UVALive - 4726 Average (斜率优化+单调队列)
- 单调队列+斜率优化的DP
- 【专辑】单调队列+斜率优化的DP
- 【专题】单调队列/斜率优化DP
- UVALive 4726Average 单调队列+斜率优化
- 单调队列,斜率优化dp 专题
- 【整理】斜率or单调队列优化dp
- 【LA4726】Average【斜率优化】【单调队列】
- LA 4726 Average (单调队列+斜率优化)
- BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)
- [BZOJ2453]维护队列(分块)
- BZOJ2453: 维护队列(分块)
- dp部分总结(单调队列,四边形优化,斜率优化,树形dp)
- 还是畅通工程
- 计算自己活了多少天 SimpleDateFormat Date getTime()
- 利用正则表达式抽取网页信息
- LeetCode-20 Valid Parentheses
- LINQ体验(13)——LINQ to SQL语句之运算符转换和ADO.NET与LINQ to SQL
- 查税( 斜率优化&单调队列维护凸包 &分块 )
- 使用Eclipse构建Maven项目
- Android使用 LruCache 缓存图片
- vs2015/MFC静态文本控件
- LINQ体验(12)——LINQ to SQL语句之对象标识和对象加载
- 第25章:Spinner的用法
- 集成测试之接口测试
- 【Java解析XML】【一】XML解析技术概括
- 狼抓兔子