博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【题解】【LibreOJ Round #6】花团 LOJ 534 时间线段树分治 背包
阅读量:5833 次
发布时间:2019-06-18

本文共 2223 字,大约阅读时间需要 7 分钟。

Prelude

题目链接:萌萌哒传送门


Solution

如果完全离线的话,可以直接用时间线段树分治来做,复杂度\(O(qv \log q)\)

现在在线了怎么办呢?
这其实是个假在线,因为每个物品的删除时间已经给你了,所以还是直接用时间线段树分治来做。
其实我是重点想谈一下复杂度的,\(O(n^{2} \log n)\)的复杂度居然都可以出到\(15000\),而且居然还跑的飞快?

1085857-20171106091120794-571327606.jpg


Code

#include 
#include
#include
#include
#include
using namespace std;typedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;typedef long double ldouble;typedef pair
pii;typedef vector
::iterator viter;const int MAXN = 15010;const int LOGN = 17;const int INF = 0x3f3f3f3f;int _w;inline void bmin( int &a, int b ) { a = b < a ? b : a;}inline void bmax( int &a, int b ) { a = b > a ? b : a;}int q, maxv, T, lastans;struct Knapsack { int f[MAXN]; void init() { for( int i = 0; i <= maxv; ++i ) f[i] = -INF; f[0] = 0; } void insert( int v, int w ) { for( int i = maxv-v; i >= 0; --i ) bmax( f[i+v], f[i]+w ); } const int &operator[]( int i ) const { return f[i]; } int &operator[]( int i ) { return f[i]; }};vector
item[MAXN<<2];Knapsack f[LOGN];int qv[MAXN];pii ins;int ql, qr;void insert( int o, int L, int R ) { if( L >= ql && R <= qr ) { item[o].push_back(ins); } else { int M = (L+R)>>1, lc = o<<1, rc = lc|1; if( ql <= M ) insert(lc, L, M); if( qr > M ) insert(rc, M+1, R); }}void query( int i, int d ) { if( qv[i] != -1 ) { int v = qv[i]; if( f[d][v] < 0 ) { puts("0 0"); lastans = 0; } else { printf( "1 %d\n", f[d][v] ); lastans = T * (f[d][v] ^ 1); } } if( i == q ) return; int op; _w = scanf( "%d", &op ); if( op == 1 ) { int v, w, e; _w = scanf( "%d%d%d", &v, &w, &e ); v -= lastans, w -= lastans, e -= lastans; ins = pii(v, w), ql = i+1, qr = e; insert(1, 0, q); } else { _w = scanf( "%d", qv+i+1 ); qv[i+1] -= lastans; }}void solve( int o, int L, int R, int d ) { for( viter it = item[o].begin(); it != item[o].end(); ++it ) f[d].insert(it->first, it->second); if( L == R ) { query(L, d); } else { int M = (L+R)>>1, lc = o<<1, rc = lc|1; f[d+1] = f[d]; solve(lc, L, M, d+1); f[d+1] = f[d]; solve(rc, M+1, R, d+1); }}int main() { _w = scanf( "%d%d%d", &q, &maxv, &T ); f[0].init(); memset(qv, -1, sizeof qv); solve(1, 0, q, 0); return 0;}

转载于:https://www.cnblogs.com/mlystdcall/p/7791623.html

你可能感兴趣的文章
45:十进制到八进制
查看>>
手机端rem如何适配_rem详解及使用方法
查看>>
线性结构-栈的顺序存储和链式存储实现
查看>>
Win7 Windows Update更新的文件默认在哪个位置
查看>>
7-nginx-keepalived配置主从双击热备
查看>>
MongoDB学习笔记~复杂条件拼接和正则的使用
查看>>
DNS服务器的搭建
查看>>
Image.FromStream与Image.FromFile使用区别
查看>>
Unity发布安卓Splash Image适应手机、平板
查看>>
设备树API
查看>>
Eclipse 找不到Server选项
查看>>
jquery 实现菜单的下拉菜单
查看>>
python入门(3)python的解释器
查看>>
Angular、React.js 和Node.js到底选谁?
查看>>
[Android] 通过Menu实现图片怀旧、浮雕、模糊、光照和素描效果
查看>>
两DD-WRT组建WDS设置
查看>>
C++简单介绍
查看>>
字母图形
查看>>
ASP.NET Core 网站发布到Linux服务器(转)
查看>>
《简明Python编程》核心笔记(1~5章)
查看>>