我是萌萌的传送门

我是另一个萌萌的传送门

脑残错误毁一下午……

其实题解早就烂大街了,然而很久之前我只知道是二分答案+主席树却想不出来这俩玩意儿怎么一块儿用的……今天又翻了几篇题解才恍然大悟,是把权值排序之后依次插入序列,用主席树维护连续和……(我菜爆了……= =)

还是讲讲大体思路吧,首先二分答案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(陈立杰)的更多相关文章

  1. [国家集训队2012]tree(陈立杰)

    [国家集训队2012]tree(陈立杰) 题目 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树.题目保证有解. INPUT 第一行V,E,need分别表示 ...

  2. [国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)

    tree 时间限制: 3 Sec  内存限制: 512 MB 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入 第一行V, ...

  3. [国家集训队2012]middle

    http://cogs.pro:8080/cogs/problem/problem.php?pid=1763 二分答案x 把区间内>=x的数设为1,<x的数设为-1 左端点在[a,b]之间 ...

  4. BZOJ2654/COGS1764 [2012国家集训队]tree(陈立杰) [生成树,二分]

    BZOJ传送门,COGS传送门 tree Description 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. Input 第一行V, ...

  5. [国家集训队2012]JZPFAR

    [国家集训队2012]JZPFAR 题目 平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号.如果有两个(或多个)点距离( ...

  6. 「国家集训队」middle

    「国家集训队」middle 传送门 按照中位数题的套路,二分答案 \(mid\),序列中 \(\ge mid\) 记为 \(1\),\(< mid\) 的记为 \(-1\) 然后只要存在一个区间 ...

  7. 数据结构(动态树):[国家集训队2012]tree(伍一鸣)

    [问题描述] 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原 ...

  8. 【国家集训队2012】tree(伍一鸣)

    Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一:  + u v c:将u到v的路径上的点的权值都加上自然数c:  - u1 v1 u2 ...

  9. [COGS 1799][国家集训队2012]tree(伍一鸣)

    Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2 ...

随机推荐

  1. software installing

    <1>.Apache防火墙配置 firewall-cmd --add-service=http firewall-cmd --add-service=https 防火墙通过80和443端口 ...

  2. ionic 学习 一

    ionic 依赖angular.在学之前,我对angular进行了一下入门. 最近在看ionic,想做一些笔记,所以,写下这个随笔,有什么不对的请多多指教,刚开始学,后面还会学Apache Cordo ...

  3. Codeforces Round #556 (Div. 2) - D. Three Religions(动态规划)

    Problem  Codeforces Round #556 (Div. 2) - D. Three Religions Time Limit: 3000 mSec Problem Descripti ...

  4. linux入门 配置网络

    我因为有自己的ssr,因此想让虚拟机共享我的ssr,并且不想搞的太麻烦,特此记录一下 1. 获取本机的ip 在命令行里输入ipconfig /all 获取本机IP,如下图所示,我本机ip为10.3.7 ...

  5. 123th LeetCode Weekly Contest Broken Calculator

    On a broken calculator that has a number showing on its display, we can perform two operations: Doub ...

  6. python+selenium+pychar安装

    python3.5(在百度输入python进入python官网-downloads-Windows-然后选择要下载的版本(可执行安装包,若电脑为32位的选择×86,若为64的选择×64)) selen ...

  7. hibernate 自动创建表中文乱码问题

    <property name="connection.url" > <![CDATA[jdbc:mysql:///test?useUnicode=true& ...

  8. 使用java配置来构建spring项目

    java配置是Spring4.x推荐的配置方式,可以完全代替xml配置,java配置是通过@Configuration和@Bean来实现的.@Configuration声明当前类是一个配置类,相当于S ...

  9. springboot整合jsp踩坑

    springboot以其高效的开发效率越来越多的用在中小项目的开发,并且在分布式开发中的使用也很广泛,springboot官方推荐的前端框架却是thymeleaf,并且默认不支持jsp,而大部分jav ...

  10. RequireJs学习笔记之data-main Entry Point

    You will typically use a data-main script to set configuration options and then load the first appli ...