[国家集训队2012]middle(陈立杰)
脑残错误毁一下午……
其实题解早就烂大街了,然而很久之前我只知道是二分答案+主席树却想不出来这俩玩意儿怎么一块儿用的……今天又翻了几篇题解才恍然大悟,是把权值排序之后依次插入序列,用主席树维护连续和……(我菜爆了……= =)
还是讲讲大体思路吧,首先二分答案M,把>=M的元素标为1,<M的标为-1,然后判定满足条件的最大子串和是否>=0,是则说明判定标准可行,否则不可行,调整下一次二分即可。但是直接暴力标记肯定会T,所以尝试对所有判定标准维护线段树来求最大子串和,然而内存开不下……考虑到如果把元素依次插入的话每次只会修改一个值,那么就把元素排序后依次插入线段树中,可持久化压内存即可。
一点细节:
鉴于子序列中间那段是肯定会用到的,所以直接拆成三段,前一段求最大后缀和,中间直接求和,后一段求最大前缀和,合并即可。因为最大前缀/后缀和是非严格最大(可以一个都不选),所以需要把b和c归到中间那段(保证一定会用上)。
贴个bzoj的代码:
/**************************************************************
Problem: 2653
User: hzoier
Language: C++
Result: Accepted
Time:936 ms
Memory:101108 kb
****************************************************************/ #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
struct node{
int sum,prefix,suffix;
node *lc,*rc;
void refresh(){
sum=lc->sum+rc->sum;
prefix=max(lc->prefix,lc->sum+rc->prefix);
suffix=max(rc->suffix,rc->sum+lc->suffix);
}
}null[maxn<<],*ptr=null;
struct A{
int d,id;
bool operator<(const A &a)const{return d<a.d;}
}a[maxn];
void build(int,int,node*&);
void modify(int,int,node*&,node*&);
void qsum(int,int,node*);
void qprefix(int,int,node*);
void qsuffix(int,int,node*);
node *root[maxn];
int n,m,x,d,s,t,q[],tmp,sum,ans,lastans=,L,R,M;
int main(){
null->lc=null->rc=null;
null->sum=null->prefix=null->suffix=;
scanf("%d",&n);
fill(root,root+n+,(node*)null);
build(,n,root[]);
for(int i=;i<=n;i++){
scanf("%d",&a[i].d);
a[i].id=i;
}
sort(a+,a+n+);
for(int i=;i<=n;i++){
x=a[i].id;
modify(,n,root[i],root[i-]);
}
scanf("%d",&m);
while(m--){
for(int i=;i<;i++){
scanf("%d",&q[i]);
q[i]+=lastans;q[i]%=n;q[i]++;
}
sort(q,q+);
L=;R=n;
while(L<=R){
M=(L+R)>>;
ans=;
s=q[];t=q[];
qsum(,n,root[M-]);
s=q[];t=q[]-;
sum=tmp=;
if(s<=t)qsuffix(,n,root[M-]);
ans+=sum;
s=q[]+;t=q[];
sum=tmp=;
if(s<=t)qprefix(,n,root[M-]);
ans+=sum;
if(ans>=)L=M+;
else R=M-;
}
printf("%d\n",lastans=a[R].d);
}
return ;
}
void build(int l,int r,node *&rt){
rt=++ptr;
rt->sum=rt->prefix=rt->suffix=r-l+;
if(l==r){
rt->lc=rt->rc=null;
return;
}
int mid=(l+r)>>;
build(l,mid,rt->lc);
build(mid+,r,rt->rc);
}
void modify(int l,int r,node *&rt,node *&pr){
*(rt=++ptr)=*pr;
if(l==r){
rt->sum=-;
rt->prefix=rt->suffix=;
return;
}
int mid=(l+r)>>;
if(x<=mid)modify(l,mid,rt->lc,pr->lc);
else modify(mid+,r,rt->rc,pr->rc);
rt->refresh();
}
void qsum(int l,int r,node *rt){
if(s<=l&&t>=r){
ans+=rt->sum;
return;
}
int mid=(l+r)>>;
if(s<=mid)qsum(l,mid,rt->lc);
if(t>mid)qsum(mid+,r,rt->rc);
}
void qprefix(int l,int r,node *rt){
if(s<=l&&t>=r){
sum=max(sum,tmp+rt->prefix);
tmp+=rt->sum;
return;
}
int mid=(l+r)>>;
if(s<=mid)qprefix(l,mid,rt->lc);
if(t>mid)qprefix(mid+,r,rt->rc);
}
void qsuffix(int l,int r,node *rt){
if(s<=l&&t>=r){
sum=max(sum,tmp+rt->suffix);
tmp+=rt->sum;
return;
}
int mid=(l+r)>>;
if(t>mid)qsuffix(mid+,r,rt->rc);
if(s<=mid)qsuffix(l,mid,rt->lc);
}
话说这份代码跑得还挺快,哈哈……

写题过程中出了两个脑残错误,两个多小时就这么搭进去了……
1.如果序列长度为偶数,按题意中位数应为中间的两个数中较大的那个,然而我一开始读成了较小的那个,然后就死活弄不清脑子一片混乱……
2.注意到求最大后缀和最后一句if(s<=mid)了没……一开始写成了if(t<=mid),然后澄清完了题意还各种跟暴力拍不上,我特么都快崩溃了……后来发现是这个脑残错误,我只想说: $%*&$^%&#$%!@&#@^&*!%$^#@%*……
看看这惨烈的提交记录……

下次写题一定要先澄清题意……脑残怎么治啊……
[国家集训队2012]middle(陈立杰)的更多相关文章
- [国家集训队2012]tree(陈立杰)
[国家集训队2012]tree(陈立杰) 题目 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树.题目保证有解. INPUT 第一行V,E,need分别表示 ...
- [国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)
tree 时间限制: 3 Sec 内存限制: 512 MB 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入 第一行V, ...
- [国家集训队2012]middle
http://cogs.pro:8080/cogs/problem/problem.php?pid=1763 二分答案x 把区间内>=x的数设为1,<x的数设为-1 左端点在[a,b]之间 ...
- BZOJ2654/COGS1764 [2012国家集训队]tree(陈立杰) [生成树,二分]
BZOJ传送门,COGS传送门 tree Description 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. Input 第一行V, ...
- [国家集训队2012]JZPFAR
[国家集训队2012]JZPFAR 题目 平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号.如果有两个(或多个)点距离( ...
- 「国家集训队」middle
「国家集训队」middle 传送门 按照中位数题的套路,二分答案 \(mid\),序列中 \(\ge mid\) 记为 \(1\),\(< mid\) 的记为 \(-1\) 然后只要存在一个区间 ...
- 数据结构(动态树):[国家集训队2012]tree(伍一鸣)
[问题描述] 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原 ...
- 【国家集训队2012】tree(伍一鸣)
Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 ...
- [COGS 1799][国家集训队2012]tree(伍一鸣)
Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2 ...
随机推荐
- [转](译)KVO的内部实现
转载自:http://www.cocoachina.com/applenews/devnews/2014/0107/7667.html 09年的一篇文章,比较深入地阐述了KVO的内部实现. K ...
- js实现checkbox全选,全部选和反选效果
效果: 源码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- sql 简单语法
1.数据库操作 create database student_info -- 创建数据库 drop database student_info -- 删除数据库 2.表操作 -- 创建表 creat ...
- Dubbo的Api+Provider+Customer示例(IDEA+Maven+Springboot+dubbo)
项目结构 dubbo-demo dubbo-api:提供api接口,一般存储实体类和接口服务 dubbo-provider:dubbo生产者提供服务,一般存储接口具体实现 dubbo-customer ...
- Ubuntu中screen命令的使用
参考GNU's Screen 官网:GNU's Scree screen的安装 sudo apt install screen 新建窗口1)可直接通过命令screen新建一个窗口,并进入窗口.但通过这 ...
- eclipse中springsource-tool-suite(sts)插件安装教程
插件的下载参照:http://www.cnblogs.com/jepson6669/p/8540157.html 用过的eclipse不能安装成功,需要重新解压新的才能安装成功,不知道为什么? 解压上 ...
- 【CSS】CSS Sprites (CSS 精灵) 技术
CSS Sprites CSS Sprites在国内很多人叫css精灵,是一种网页图片应用处理方式.它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去,这样一来,当访问该页面时,载入的图片就不 ...
- hadoop Shell命令详解
调用文件系统(FS)Shell命令应使用bin/hadoop fs <args>的形式.所有的的FS shell命令使用URI路径作为参数.URI路径详解点击这里. 1.cat说明:将路径 ...
- .NET环境下的DPAPI加密编程
Windows的本地加密保护机制提供了简单的调用接口,密钥的生成.保护等事项一概由系统来处理,其编程接口称为DPAPI.这一加密保护机制的边界是用户登录帐户或者本地计算机系统,使用操作系统设定的加密处 ...
- rest webapi 返回数据
webapi可以直接返回一个对象,也可以返回json 一.返回一个对象例子 [System.Web.Mvc.AllowAnonymous] [System.Web.Http.HttpGet] publ ...