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

题目描述

《贪玩蓝月》是目前最火爆的网页游戏。在游戏中每个角色都有若干装备,每件装备有一个特征值 $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. python进阶04 装饰器、描述器、常用内置装饰器

    python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...

  2. [Android]四大组件的运行状态

    Activity的主要作用是展示一个界面并和用户交互,它扮演的是一种前台界面的角色. Service是一种计算型组件,用于在后台执行一系列计算任务.Service有两种状态:启动状态和绑定状态.启动状 ...

  3. Selenium 开源书(一): Selenium历史

    Selenium历史 Selenium最初由Jason Huggins于2004年开发,作为ThoughtWorks的内部工具.Huggins后来加入了ThoughtWorks的其他程序员和测试人员, ...

  4. HTML标签的三种类型

    HTML标签的类型分为三种:行内元素,行内块元素,块级元素 而标签的属性是可以转换的 display:inline: 转换为行内元素 display:linline-block 转换为行内块元素 di ...

  5. Linux开机启动服务

    一.添加启动脚本 vim /etc/rc.d/rc.local sh /home/glt/apache-tomcat-/bin/email.sh 二.启动服务 systemctl enable rc- ...

  6. spark RPC详解

    前段时间看spark,看着迷迷糊糊的.最近终于有点头绪,先梳理了一下spark rpc相关的东西,先记录下来. 1,概述 个人认为,如果把分布式系统(HDFS, HBASE,SPARK等)比作一个人, ...

  7. SyntaxHighlighter

    SyntaxHighlighter uses separate syntax files called brushes to define its highlighting functionality ...

  8. C#里边的控件缩写大全(比较规范)

    标准控件1 btn Button 2 chk CheckBox 3 ckl CheckedListBox 4 cmb ComboBox 5 dtp DateTimePicker 6 lbl Label ...

  9. return void ajax

    public class UserInfo { private String name; private Integer age; public String getName() { return n ...

  10. c#基础 path 类的各种套路

    string str = @"C:\3000soft\Red Spider\Data\Message\老赵.wav"; //获得文件名 Console.WriteLine(Path ...