考试时候怎么就是没想到线段树分治呢?

题目描述

《贪玩蓝月》是目前最火爆的网页游戏。在游戏中每个角色都有若干装备,每件装备有一个特征值 $w$ 和一个战斗力 $v$ 。在每种特定的情况下,你都要选出特征值的和对 $\rm MOD$ 取模后在一段范围内的装备,而角色死亡时自己的装备会爆掉。每个角色的物品槽可以看成一个双端队列,得到的装备会被放在两端,自己的装备爆掉也会在两端被爆。

现在我们有若干种事件和询问,如下所示:

  • IF w v:在前端加入一件特征值为 $w$ 战斗力为 $v$ 的装备
  • IG w v:在后端加入一件特征值为 $w$ 战斗力为 $v$ 的装备
  • DF:删除最前端的装备
  • DG:删除最后端的装备
  • QU l r:在当前的装备中选取若干装备,他们的和对 $\rm MOD$ 取模后在 $[l, r]$ 中,使得这些装备的战斗力之和最大

为了锻炼你的水平,请尽量使用在线做法。


题目分析

做法一:线段树分治

考虑一下w,v强制在线的做法。

注意到这个在线是个“半在线”:因为虽然w,v是被加密过的,但是操作种类是可见的。那么就可以预先处理处每一个物品的存在时间区间,因此这样对操作进行线段树分治就是个离线问题了。

 #include<bits/stdc++.h>
typedef long long ll;
const int maxn = ; int m,p,tag;
ll ans[maxn];
struct QRs
{
char opt[];
int l,r;
}qr[maxn];
struct Opt
{
int s,t,w,v;
Opt(int a=, int b=, int c=, int d=):s(a),t(b),w(c),v(d) {}
}rec[maxn];
struct node
{
ll f[],g[];
void init()
{
memset(f, -0x3f3f3f3f, sizeof f), f[] = ;
}
void update(int w, int v)
{
for (int i=; i<p; i++) g[i] = f[i];
for (int i=; i<p; i++) //x+w=i
f[i] = std::max(f[i], g[(i-w+p)%p]+v);
}
ll query(int l, int r)
{
ll ret = -;
for (int i=l; i<=r; i++) ret = std::max(f[i], ret);
return ret;
}
}sta;
typedef std::vector<Opt> vec;
std::deque<int> deq;
vec opt; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void solve(int l, int r, vec opt, node sta)
{
vec L,R;
int mid = (l+r)>>;
for (int i=, mx=opt.size(); i<mx; i++)
{
int s = opt[i].s, t = opt[i].t;
if (s <= l&&r <= t) sta.update(opt[i].w, opt[i].v);
else{
if (s <= mid) L.push_back(opt[i]);
if (t > mid) R.push_back(opt[i]);
}
}
if (l==r){
if (qr[l].opt[]=='Q') ans[l] = sta.query(qr[l].l, qr[l].r);
}else solve(l, mid, L, sta), solve(mid+, r, R, sta);
}
int main()
{
scanf("%*d"), m = read(), p = read();
for (int i=, tmp; i<=m; i++)
{
scanf("%s",qr[i].opt);
if (qr[i].opt[]=='I'){
qr[i].l = read()%p, qr[i].r = read(), ++tag;
if (qr[i].opt[]=='F') deq.push_front(tag);
else deq.push_back(tag);
opt.push_back(Opt(i, m, qr[i].l, qr[i].r));
}
if (qr[i].opt[]=='Q')
qr[i].l = read(), qr[i].r = read();
if (qr[i].opt[]=='D'){
if (qr[i].opt[]=='F')
tmp = deq.front(), deq.pop_front();
else tmp = deq.back(), deq.pop_back();
opt[tmp-].t = i-;
}
}
sta.init();
solve(, m, opt, sta);
for (int i=; i<=m; i++)
if (qr[i].opt[]=='Q') printf("%lld\n",ans[i]);
return ;
}

做法二:思维题  栈  启发式

可能要先咕着

【线段树分治 01背包】loj#6515. 「雅礼集训 2018 Day10」贪玩蓝月的更多相关文章

  1. loj #6515. 「雅礼集训 2018 Day10」贪玩蓝月

    \(\color{#0066ff}{输入样例}\) 0 11 10 QU 0 0 QU 1 9 IG 14 7 IF 3 5 QU 0 9 IG 1 8 DF QU 0 4 IF 1 2 DG QU ...

  2. 「雅礼集训 2018 Day10」贪玩蓝月

    题目链接 题意分析 我们考虑维护两个栈 分别支持左边的插入删除以及右边的插入删除 然后对于两两个栈的我们需要用背包求出最优答案 注意 删除时如果不够的话 我们需要从另一个栈中取出一半加入另一个栈中 注 ...

  3. Loj #6503. 「雅礼集训 2018 Day4」Magic

    Loj #6503. 「雅礼集训 2018 Day4」Magic 题目描述 前进!前进!不择手段地前进!--托马斯 · 维德 魔法纪元元年. 1453 年 5 月 3 日 16 时,高维碎片接触地球. ...

  4. LOJ#6048. 「雅礼集训 2017 Day10」数列(线段树)

    题面 传送门 题解 我的做法似乎非常复杂啊-- 首先最长上升子序列长度就等于把它反过来再接到前面求一遍,比方说把\(2134\)变成\(43122134\),实际上变化之后的求一个最长上升子序列和方案 ...

  5. 【卡常 bitset 分块】loj#6499. 「雅礼集训 2018 Day2」颜色

    好不容易算着块大小,裸的分块才能过随机极限数据:然而这题在线的数据都竟然是构造的…… 题目描述 有 $n$ 个数字,第 $i$ 个数字为 $a_i$. 有 $m$ 次询问,每次给出 $k_i$ 个区间 ...

  6. [loj 6496]「雅礼集训 2018 Day1」仙人掌

    传送门 Description 给出一张 \(n\)个点 \(m\)条边的无向连通图,其中每条边至多属于一个简单环,保证没有自环,可能有重边.你需要为其中每条边定向,其中第 \(i\)个点的出度不能超 ...

  7. LOJ #6509. 「雅礼集训 2018 Day7」C

    神仙题 LOJ #6509 题意 给定一棵树,点权为0/1,每次随机一个点(可能和之前所在点相同)走到该点并将其点权异或上1 求期望的移动距离使得所有点点权相同 题解 根本不会解方程 容易发现如果一个 ...

  8. LOJ#6503.「雅礼集训 2018 Day4」Magic[容斥+NTT+启发式合并]

    题意 \(n\) 张卡牌 \(m\) 种颜色,询问有多少种本质不同的序列满足相邻颜色相同的位置数量等于 \(k\). 分析 首先本质不同不好直接处理,可以将同种颜色的卡牌看作是不相同的,求出答案后除以 ...

  9. LOJ#6049. 「雅礼集训 2017 Day10」拍苍蝇(计算几何+bitset)

    题面 传送门 题解 首先可以用一个矩形去套这个多边形,那么我们只要枚举这个矩形的左下角就可以枚举完所有多边形的位置了 我们先对每一个\(x\)坐标开一个\(bitset\),表示这个\(x\)坐标里哪 ...

随机推荐

  1. 省选准备 MISTAKE 大全

    2019-03-29 [NOI2016]网格 如果是矩形,要记得考虑n或m=1的情况,不要潜意识里就以为矩形就是接近正方形的那种理想矩形. 写bool型的函数,return 的语句要想清楚,不要放错位 ...

  2. EOS 主节点同步

    一.从github克隆主网代码仓库 git clone https://github.com/EOSIO/eos --recursive 二.编译与安装EOS环境 cd ~/eos ./eosio_b ...

  3. maven 参考

    系列文章,通俗易懂,可以看看 http://www.cnblogs.com/AlanLee/category/918828.html

  4. Codeforces Round #564 (Div. 2) A. Nauuo and Votes

    链接:https://codeforces.com/contest/1173/problem/A 题意: Nauuo is a girl who loves writing comments. One ...

  5. Python 开发基础-字符串类型讲解(字符串方法)-2

    s = 'Hello World!'print(s.index('W',0,9))#返回某个字母的索引值,本例返回6.没有该字母会报错,和FIND比较像,find不会报错,没找到会返回-1print( ...

  6. 从两个不同的ServiceProvider说起

    从两个不同的ServiceProvider说起 我们一致在说 ASP.NET Core广泛地使用到了依赖注入,通过前面两个系列的介绍,相信读者朋友已经体会到了这一点.由于前面两章已经涵盖了依赖注入在管 ...

  7. Linux学习笔记——如何使用echo指令向文件写入内容

    0.前言     本文总结如何使用echo命令向文件中写入内容,例如使用echo指令覆盖文件内容,使用echo指令向文件追加内容,使用echo指令往文件中追加制表符.     echo向文件中输出内容 ...

  8. WebStorm技巧-常用快捷键

      Ctrl+/ 或 Ctrl+Shift+/ 注释(// 或者/*-*/ ) Shift+F6 重构-重命名 Ctrl+X 删除行 Ctrl+D 复制行 Ctrl+G 查找行 Ctrl+Shift+ ...

  9. .net创建activex实现摄像头拍照

    using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices ...

  10. IDEA对比文件

    和另一个文件对比:右击文件,选择另一个文件 和剪切板的内容对比:右击代码区域