zoukankan      html  css  js  c++  java
  • CF500F New Year Shopping [线段树分治,背包]

    不会奇怪的背包科技,只能用线段树分治了。

    // by Isaunoya
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    struct io {
    	char buf[1 << 25 | 3], *s;
    	int f;
    	io() { f = 0, buf[fread(s = buf, 1, 1 << 25, stdin)] = '
    '; }
    	io& operator >> (int&x) {
    		for(x = f = 0; !isdigit(*s); ++s) f |= *s  == '-';
    		while(isdigit(*s)) x = x * 10 + (*s++ ^ 48);
    		return x = f ? -x : x, *this;
    	}
    };
    
    struct io_out {
    	char buf[1 << 25 | 3], *s = buf;
    	~io_out() { fwrite(buf, 1, s - buf, stdout); }
    	void write(int x) { if(x > 9) write(x / 10); *s++ = x % 10 ^ '0'; }
    	io_out& operator << (int x) {
    		if(x < 0) x = -x, *s++ = '-';
    		write(x); return *this;
    	}
    	io_out& operator << (char x) { *s++ = x; return *this; }
    } out;
    
    
    int n, p, q;
    const int lg = 40;
    const int lim = 2e4 + 42;
    const int maxn = 4444;
    int st[lg][maxn], f[maxn], top;
    int c[maxn], h[maxn];
    
    vector <int> vec[lim << 2];
    void upd(int ql, int qr, int l, int r, int p, int x) {
    	if(ql <= l && r <= qr) {
    		vec[p].push_back(x);
    		return;
    	}
    	int mid = l + r >> 1;
    	if(ql <= mid)
    		upd(ql, qr, l, mid, p << 1, x);
    	if(qr > mid)
    		upd(ql, qr, mid + 1, r , p << 1 | 1 , x);
    	return ;
    }
    
    const int maxq = 2e4 + 42;
    int a[maxq], b[maxq], ans[maxq];
    vector <int> tq[lim];
    
    void takenew() {
    	++ top;
    	for(int i = 0 ; i <= 4000 ; i ++) st[top][i] = f[i];
    }
    
    void back() {
    	-- top;
    	for(int i = 0 ; i <= 4000 ; i ++) f[i] = st[top][i];
    }
    
    void solve(int l, int r, int p) {
    	for(int id : vec[p])
    		for(int i = 4000; i >= c[id]; i --) f[i] = max(f[i], f[i - c[id]] + h[id]);
    	takenew();
    	if(l == r) { for(int x : tq[l]) ans[x] = f[b[x]]; }
    	else {
    		int mid = l + r >> 1;
    		solve(l, mid, p << 1), solve(mid + 1, r, p << 1 | 1);
    	}
    	back();
    }
    
    signed main() {
    #ifdef LOCAL
    	freopen("testdata.in", "r", stdin);
    #endif
    	io in;
    	in >> n >> p;
    	for(int i = 1 ; i <= n ; i ++) {
    		int t ;
    		in >> c[i] >> h[i] >> t;
    		upd(t, t + p - 1, 1 , lim , 1, i);
    	}
    	in >> q;
    	for(int i = 1 ; i <= q ; i ++) {
    		in >> a[i] >> b[i];
    		tq[a[i]].push_back(i);
    	}
    	solve(1, lim, 1);
    	for(int i = 1 ; i <= q ; i ++)
    		out << ans[i] << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    HTML学习记录之HTML组成原理 PHP学习铺垫
    最长上升子序列(Longest increasing subsequence)
    进程保护(二)
    进程保护(一)
    屏幕广播的实现(三)
    vs2010 调试快捷键
    [整理]C#.Net的常见面试试题附答案(ZT)
    C# 中处理字符串常用的函数及方法详细说明
    Linux 系统下 /etc/group 档案结构
    C# Thread 多种写法总结
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12818865.html
Copyright © 2011-2022 走看看