\(\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 9

\(\color{#0066ff}{输出样例}\)

0
-1
12
8
9

\(\color{#0066ff}{数据范围与提示}\)

\(\color{#0066ff}{题解}\)

维护两个栈,一个是前面插入,一个是后面插入,每次插入的时候跑一遍背包

删除的时候,如果一个栈空了,那么把另一个栈的一半弄过来(保证复杂度),暴力处理一下DP

对于询问,对于每一个\(x\in[1,mod]\),我们可以找到一个区间使得\([(L+x)\%mod,(R+x)\%mod]就是给的询问的[l,r]\)

我们只需要一个栈的DP数组的x位置的值和另一个数组一段区间的最大值,用这个更新答案就行

#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
template<typename T> T chkmax(T &a, const T &b) { return a < b? a = b : b; }
template<typename T> T chkmin(T &a, const T &b) { return a < b? a : a = b; }
const int maxn = 5e4 + 10;
const int maxm = 505;
LL st[maxn][20], f[2][maxn][maxm];
int top[2], mod, lg[maxn], inf;
std::pair<LL, LL> t[2][maxn];
char opt[22];
void predoit() {
memset(f, 0xcf, sizeof f);
inf = -f[0][0][0];
f[0][0][0] = f[1][0][0] = 0;
lg[0] = -1;
for(int i = 1; i < maxn; i++) lg[i] = lg[i >> 1] + 1;
}
void ins(bool k, int now, std::pair<LL, LL> mp) {
t[k][now] = mp;
for(int i = 0; i < mod; i++) f[k][now][i] = f[k][now - 1][i];
for(int i = 0; i < mod; i++) chkmax(f[k][now][(i + mp.first) % mod], f[k][now - 1][i] + mp.second);
}
void del(bool k) {
if(top[k]) return (void)(top[k]--);
int mid = (top[k ^ 1] + 1) >> 1;
for(int i = 1; i <= mid; i++) t[k][mid - i + 1] = t[k ^ 1][i], t[k ^ 1][i] = t[k ^ 1][i + mid];
top[k] = mid - 1, top[k ^ 1] = top[k ^ 1] & 1? mid - 1 : mid;
for(int i = 1; i <= top[k]; i++) ins(k, i, t[k][i]);
for(int i = 1; i <= top[k ^ 1]; i++) ins(k ^ 1, i, t[k ^ 1][i]);
}
LL getans(int l, int r) {
int len = lg[r - l + 1];
return std::max(st[l][len], st[r - (1 << len) + 1][len]);
} LL query(int l, int r) {
LL ans = -inf;
for(int i = 0; i < mod; i++) st[i][0] = f[0][top[0]][i];
for(int j = 1; j <= lg[mod]; j++)
for(int i = 0; i + (1 << j) <= mod; i++)
st[i][j] = std::max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
for(int i = 0; i < mod; i++) {
if(f[1][top[1]][i] < 0) continue;
int L = l - i, R = r - i;
(L += mod) %= mod, (R += mod) %= mod;
if(L <= R) chkmax(ans, f[1][top[1]][i] + getans(L, R));
else chkmax(ans, f[1][top[1]][i] + std::max(getans(L, mod - 1), getans(0, R)));
}
return ans < 0? -1 : ans;
}; int main() {
in(); int T = in(); LL x, y; mod = in();
predoit();
while(T --> 0) {
scanf("%s", opt);
if(opt[0] == 'I') x = in(), y = in(), ins(opt[1] == 'G', ++top[opt[1] == 'G'], std::make_pair(x % mod, y));
if(opt[0] == 'D') del(opt[1] == 'G');
if(opt[0] == 'Q') x = in(), y = in(), printf("%lld\n", query(x, y));
}
return 0;
}

loj #6515. 「雅礼集训 2018 Day10」贪玩蓝月的更多相关文章

  1. 【线段树分治 01背包】loj#6515. 「雅礼集训 2018 Day10」贪玩蓝月

    考试时候怎么就是没想到线段树分治呢? 题目描述 <贪玩蓝月>是目前最火爆的网页游戏.在游戏中每个角色都有若干装备,每件装备有一个特征值 $w$ 和一个战斗力 $v$ .在每种特定的情况下, ...

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

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

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

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

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

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

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

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

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

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

  7. LOJ#6047. 「雅礼集训 2017 Day10」决斗(set)

    题面 传送门 题解 这么简单一道题我考试的时候居然只打了\(40\)分暴力? 如果我们把每个点的\(a_i\)记为\(deg_i-1\),其中\(deg_i\)表示有\(deg_i\)个数的\(A_i ...

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

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

  9. LOJ#6504. 「雅礼集训 2018 Day5」Convex(回滚莫队)

    题面 传送门 题解 因为并不强制在线,我们可以考虑莫队 然而莫队的时候有个问题,删除很简单,除去它和前驱后继的贡献即可.但是插入的话却要找到前驱后继再插入,非常麻烦 那么我们把它变成只删除的回滚莫队就 ...

随机推荐

  1. Python之多进程和多线程

    目标: 1.os.fork简单示例 2.使用os.fork多进程测试IP是否在线 3.使用os.fork多进程解决tcpserver多客户端连接问题 4.多线程测试IP地址是否在线 1.os.fork ...

  2. spring4-2-bean配置-10-通过FactoryBean配置bean

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAk8AAAFHCAIAAAA3Hj/JAAAgAElEQVR4nO2dzdX0rA2Gp6asclwQTW

  3. Nginx概述、安装及配置详解

    nginx概述 nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外 ...

  4. spark reduceByKey

    reduce(binary_function) reduce将RDD中元素前两个传给输入函数,产生一个新的return值,新产生的return值与RDD中下一个元素(第三个元素)组成两个元素,再被传给 ...

  5. code2039 骑马修栏杆

    欧拉通路: find_circuit(结点i){ 当结点i有邻居时 选择任意一个邻居j: 删除边(i,j)或者做访问标记: find_circuit(结点j): 输出或存储节点i: } 本题注意点的编 ...

  6. 浅谈css float

    相信许多许多Web前端的朋友一定被float这个属性给困扰过吧,有时候用它来布局很方便,能够实现元素快速的水平排列,但有时候它又像一个精灵,让人无法琢磨透它方位.在网上也看了一些关于float的帖子, ...

  7. Linux下软件常见安装方式

    pasting  分类: Linux2007-12-08 16:31 1909人阅读 评论(0) 收藏 举报 linuxredhat脚本文档managerfile        Linux下软件安装主 ...

  8. C++ generic tools -- from C++ Standard Library

    今晚学了一下C++标准程序库, 来简单回顾和总结一下. 1.pair 结构体 // defined in <utility> , in the std namespace namespac ...

  9. BBS项目(2)

    我们实现登录功能的随机验证码的产生 views.py def get_random_color(): return ( # 创建三个0-255的随机数 random.randint(0, 255), ...

  10. 使用GeoServer+OpenLayers发布和调用WMTS、Vector Tile矢量切片服务 | Publishing and Calling WMTS, Vector Tile Service Using GeoServer + OpenLayers

    Web GIS系列: 1.搭建简易Web GIS网站:使用GeoServer+PostgreSQL+PostGIS+OpenLayers3 2.使用GeoServer+QGIS发布WMTS服务 3.使 ...