题目大意

  有一个双端队列,每个元素是一个物品,每个物品有体积和价值两个属性。

  有 \(n\) 个操作,分为 \(5\) 种:前后端插入删除,还有询问:选出一些物品,满足这些物品的体积之和模 \(p\) 在 \([l,r]\) 之间,问你价值和最大是多少。

  \(n\leq 50000,p\leq 500\)

题解

离线做法

  处理出每个物品加入队列的时间和删除的时间,插入到线段树里面分治就好了。

  时间复杂度:\(O(np\log n)\)

在线做法

  考虑对于一个队列,从中间向两边各建一个可持久化栈维护两边中间到两边的物品加在一起的信息。

  如果删除后把某一个栈的栈底删掉了,就从中间开始重构这两个栈。

  对于一个询问,枚举左边的物品体积是多少,然后右边的物品体积就是一个区间。

  可以按照 \(r-l+1\) 分块,这样每次询问就是块内的一个前缀和一个后缀。

  时间复杂度:\(O(np)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<functional>
#include<cmath>
#include<vector>
//using namespace std;
using std::min;
using std::max;
using std::swap;
using std::sort;
using std::reverse;
using std::random_shuffle;
using std::lower_bound;
using std::upper_bound;
using std::unique;
using std::vector;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef std::pair<int,int> pii;
typedef std::pair<ll,ll> pll;
void open(const char *s){
#ifndef ONLINE_JUDGE
char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
void open2(const char *s){
#ifdef DEBUG
char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
int rd(){int s=0,c,b=0;while(((c=getchar())<'0'||c>'9')&&c!='-');if(c=='-'){c=getchar();b=1;}do{s=s*10+c-'0';}while((c=getchar())>='0'&&c<='9');return b?-s:s;}
void put(int x){if(!x){putchar('0');return;}static int c[20];int t=0;while(x){c[++t]=x%10;x/=10;}while(t)putchar(c[t--]+'0');}
int upmin(int &a,int b){if(b<a){a=b;return 1;}return 0;}
int upmax(int &a,int b){if(b>a){a=b;return 1;}return 0;}
const int N=50010;
const int P=510;
const ll inf=0x3fffffffffffffffll;
struct info
{
ll a[P];
ll &operator [](int x)
{
return a[x];
}
void clear()
{
memset(a,0xc0,sizeof a);
a[0]=0;
}
};
int n,p;
info a1[N],a2[N];
int l,r,mid;
int t1,t2;
int w[2*N],v[2*N];
void init()
{
l=50001;
r=50000;
mid=50000;
a1[0].clear();
a2[0].clear();
}
void addl(int x)
{
t1++;
a1[t1]=a1[t1-1];
for(int i=0;i<p;i++)
a1[t1][(i+w[x])%p]=max(a1[t1][(i+w[x])%p],a1[t1-1][i]+v[x]);
}
void addr(int x)
{
t2++;
a2[t2]=a2[t2-1];
for(int i=0;i<p;i++)
a2[t2][(i+w[x])%p]=max(a2[t2][(i+w[x])%p],a2[t2-1][i]+v[x]);
}
void rebuild()
{
mid=(l+r)>>1;
t1=0;
t2=0;
for(int i=mid;i>=l;i--)
addl(i);
for(int i=mid+1;i<=r;i++)
addr(i);
}
int pre[P],suf[P];
void query()
{
int ql,qr;
scanf("%d%d",&ql,&qr);
int len=qr-ql+1;
ll s=-inf;
for(int i=0;i<p;i++)
{
if(i%len==0)
s=-inf;
s=max(s,a1[t1][i]);
pre[i]=s;
}
s=-inf;
for(int i=p-1;i>=0;i--)
{
if(i%len==len-1)
s=-inf;
s=max(s,a1[t1][i]);
suf[i]=s;
}
ll ans=-1;
// for(int i=0;i<p;i++)
// for(int j=0;j<p;j++)
// if((i+j)%p>=ql&&(i+j)%p<=qr)
// {
// ans=max(ans,a1[t1][i]+a2[t2][j]);
// if(ans==481594)
// int xxx=1;
// }
for(int i=0;i<p;i++)
{
int _l=ql-i;
int _r=qr-i;
if(_l<0)
_l+=p;
if(_r<0)
_r+=p;
ans=max(ans,a2[t2][i]+max(pre[_r],suf[_l]));
int z=p/len*len;
if(_l>_r&&_l<z)
ans=max(ans,a2[t2][i]+suf[z]);
}
printf("%lld\n",ans);
}
char op[10];
void gao()
{
scanf("%s",op);
if(op[0]=='I')
{
if(op[1]=='F')
{
l--;
scanf("%d%d",&w[l],&v[l]);
w[l]%=p;
addl(l);
}
else
{
r++;
scanf("%d%d",&w[r],&v[r]);
w[r]%=p;
addr(r);
}
}
else if(op[0]=='D')
{
if(op[1]=='F')
{
l++;
t1--;
if(l>mid+1)
rebuild();
}
else
{
r--;
t2--;
if(r<=mid+1)
rebuild();
}
}
else
{
query();
}
}
int main()
{
open("loj6515");
rd();
scanf("%d%d",&n,&p);
init();
for(int i=1;i<=n;i++)
{
if(i==75)
int xxx=1;
gao();
// if(op[0]=='Q')
// printf("%d\n",i);
}
return 0;
}

【LOJ6515】贪玩蓝月的更多相关文章

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

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

  2. 2019.01.13 loj#6515. 贪玩蓝月(线段树分治+01背包)

    传送门 题意简述:有一个初始为空的双端队列,每次可以在队首和队尾插入或弹出一个二元组(wi,vi)(w_i,v_i)(wi​,vi​),支持询问从当前队列中选取若干个元素是的他们的和对 MODMODM ...

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

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

  4. 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 ...

  5. Python 正则表达式 (python网络爬虫)

    昨天 2018 年 01 月 31 日,农历腊月十五日.20:00 左右,152 年一遇的月全食.血月.蓝月将今晚呈现空中,虽然没有看到蓝月亮,血月.月全食也是勉强可以了,还是可以想像一下一瓶蓝月亮洗 ...

  6. 基于H5的混合开发介绍(一)WebView

    转自: https://www.cnblogs.com/sanchang/p/9261461.html 一 WebView到底是什么    1 WebView是一种控件,它基于webkit引擎,因此具 ...

  7. python语言学习--2

    第三天1. python代码缩进规则:具有相同缩进的代码被视为代码块,4个空格, 不要使用Tab,更不要混合Tab和空格,否则很容易造成因为缩进引起的语法错误. 2.list:[...] 用(名称任意 ...

  8. html5常见新增标签

    本文内容: header nav article footer section aside datalist 音频标签: audio 视频标签: video 插入媒体标签: embed 新增input ...

  9. Python爬取电影天堂指定电视剧或者电影

    1.分析搜索请求 一位高人曾经说过,想爬取数据,要先分析网站 今天我们爬取电影天堂,有好看的美剧我在上面都能找到,算是很全了. 这个网站的广告出奇的多,用过都知道,点一下搜索就会弹出个窗口,伴随着滑稽 ...

随机推荐

  1. c#进阶一:使用ILDASM来查看c#中间语言

    平时工作的时候总是使用ctrl c+ctrl v去快速开发实现业务功能,但是在工作之余,我们也应该要注意静下心来去学习和提高自己.进阶的文章随性来写,不定时更新.希望可以和大家共同学习,共同进步.今天 ...

  2. 微擎模块的安装文件manifest.xml

    微擎在安装或卸载模块时会根据manifest.xml生成(或删除)数据库中相应记录,并执行manifest.xml里指定的脚本. manifest.xml文件内容详细介绍如下: manifest - ...

  3. FineReport数据库连接(oracle+plsql)(1)

    一.  数据库建表 数据库是Oracle12c,工具是plsql.具体操作百度即可,此处不赘述.(图1) 图1 二.  FineReport中建立数据库连接 在上方选项卡中单击服务器,选择定义数据连接 ...

  4. DVWA 黑客攻防演练(十四)CSRF 攻击 Cross Site Request Forgery

    这么多攻击中,CSRF 攻击,全称是 Cross Site Request Forgery,翻译过来是跨站请求伪造可谓是最防不胜防之一.比如删除一篇文章,添加一笔钱之类,如果开发者是没有考虑到会被 C ...

  5. ext前后台数据传输的标准化

    一.标准化的数据传输是什么 这里所说的标准化主要是指,使用代理提交数据时,格式必须统一化.标准化,而服务器返回的数据格式也必须是标准化的数据. 简言之,使用代理提交数据时,前台--->后台,后台 ...

  6. [20190416]process allocation latch.txt

    [20190416]process allocation latch.txt --//看链接:http://andreynikolaev.wordpress.com/2010/12/16/hidden ...

  7. sql Server 2008 数据库自动备份维护计划

    数据库中右键-‘管理’-新建维护计划 创建执行计划,设置备份时间 点击保存 完成 执行后报  ‘’错误5:拒绝访问 ’,时需到文件目录‘属性’→‘安全’设置用户的 ‘写入’ 权限

  8. JDBC实现简单增删改查

    JDBC全称为:Java Data Base Connectivity (java数据库连接),主要用于java与数据库的链接. 整个链接过程如下图: 1.数据库驱动:Driver 加载mysql驱动 ...

  9. Vue.js03:v-model实现简易计算器

    v-model用于数据的双向绑定.bug不少,凑合看吧,主要是练习v-model. <!DOCTYPE html> <html lang="en"> < ...

  10. 【spring源码分析】IOC容器初始化(一)

    前言:spring主要就是对bean进行管理,因此IOC容器的初始化过程非常重要,搞清楚其原理不管在实际生产或面试过程中都十分的有用.在[spring源码分析]准备工作中已经搭建好spring的环境, ...