旋转子段 (思维stl)
题目:

大概意思就是给你一个序列,你可以选择一段区间使它左右翻折一遍,然后呢,从1到n找一遍,看a[i]==i的数最多是多少。
其实刚才我已经把暴力思路说出来了,枚举每一个区间长度,枚举每一个左端点,再查询a[i]的值,时间复杂度O(n^3^)。
稍微优化一点,枚举每一个中点,左右扩展的同时查询,复杂度O(n^2^)(注意中点有可能不是点,可能是两个点中间,不考虑这个会被卡20分)
正解:
我们需要考虑下面两个性质:
性质1:对于一个点i,如果想让它满足条件,它的翻折区间是从i到a[i],在这个区间内满足a[k]+k==a[i]+i的点会在i翻折的同时也翻折到正确的位置,不满足的一定不会翻到正确的位置。
证明:显然,关于(a[i]+i)/2对称的点,一定满足(a[k]+k)/2==(a[i]+i)/2,只有满足这个条件k跟i才共用同一个中点,从而能一起翻折到正确的位置,不满足这个条件的一定翻不到正确的位置
我们对于所有的a[i]+i值,开一个向量存储所有的i。简而言之,就是开一个向量数组,把a[i]+i相同的元素都放到一个向量里面。
我们对于每一个向量,先根据翻折区间的大小,从小到大排序一遍,我们先处理小区间,再处理大区间(因为大区间会顺便把小区间的也翻折过去,会漏一些情况)。
对于每一个翻折区间,我们的结果是:
区间左侧的满足条件的i+区间右侧的满足条件的i+区间内翻折后满足条件的i(废话连篇)
对于区间左侧与右侧的满足条件的i,我们可一通过预处理(前缀和+后缀和)来做到O(1)查询,关键在怎么处理这个区间内的情况,这需要我们的下一个性质。
性质2:
一个区间内部的满足条件的i的数量与这个区间是满足a[i]+i相等的区间的正序排序位置相等(好复杂)
上面是我胡编的性质,我们处理这个性质需要结合刚才的vector来考虑。
对于一些a[i]+i相等的数们,我们把他们都放进了一个vector里面,然后都排序好了,然后这个i是排完序后的第几位,i~a[i]这个区间里面就有几个满足条件的数。
???是不是很神奇,竟然这么简单?下面是证明
对于相等a[i]+i的最小的区间,我们不妨设他为k~a[k],已知它是最小的满足a[k]+k=a[i]+i的区间,那在这个区间翻折后,也之可能有这一个k变成了满足条件的数。首先,我们知道,只有a[i]+i=a[k]+k的区间通过这个翻折才能变为满足i=a[i]的数,而k~a[k]的区间是等值的区间中最小的那个,所以在k~a[k]以内的数,只能不满足a[i]+i=a[k]+k,(满足的都比k~a[k]这个区间大)
所以,k~a[k]这个区间翻折之后也就只有一个满足条件的i就是k啦。
以此类推,第二大的区间内部也只有那个区间的两端和这个k满足条件,翻折后满足条件的i有2个。
第三大的区间里翻折后满足条件的有3个,第四大的有4个……
所以我们知道对于a[i]+i相等的区间,第几大的区间翻折后区间里面就有几个满足条件a[i]==i的数。
思路差不多了上代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+10;
int n,a[maxn],L[maxn],R[maxn];//L数组是从1到i的满足a[i]==i的数量,R数组是i到n的
vector<int> q[maxn];
int now;
bool cmp(int x,int y){
return abs(now-2*x)<abs(now-2*y);
//now是现在的a[i]+i的和,翻折区间的长度=abs(a[i]-i)=abs(ans-i-i);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
q[a[i]+i].push_back(i);//记住这里的向量里面保存下标
if(a[i]==i)L[i]=L[i-1]+1;
else L[i]=L[i-1];
}
for(int i=n;i>=1;i--){
if(a[i]==i)R[i]=R[i+1]+1;
else R[i]=R[i+1];
}
//以上是初始化操作
int ans=0;
for(int i=2;i<=2*n;i++){
now=i;
if(q[i].empty())continue;
sort(q[i].begin(),q[i].end(),cmp);
for(int j=0;j<q[i].size();j++){
int l=q[i][j],r=now-q[i][j];//当前区间的左右端点
if(l>r)swap(l,r);
ans=max(ans,L[l-1]+R[r+1]+j+1);
//因为j=0的时候是第一个区间,所以加的是j+1。
}
}
printf("%d",ans);
return 0;
}
旋转子段 (思维stl)的更多相关文章
- 8.7 NOIP模拟测试14 旋转子段+走格子+ 柱状图
T1 旋转子段 30% 暴力枚举起点和长度,暴力判断,o(n3) 不知道为什么我拿了40分... 60% 每一个点都有一个固定的旋转中心可以转成固定点,枚举旋转点和长度. 100% 用一个vecto ...
- [CSP-S模拟测试]:旋转子段(数学)
题目描述 $ZYL$有$N$张牌编号分别为$1,2,...,N$.他把这$N$张牌打乱排成一排,然后他要做一次旋转使得旋转后固定点尽可能多.如果第$i$个位置的牌的编号为$i$,我们就称之为固定点.旋 ...
- NOIP模拟测试14「旋转子段·走格子·柱状图」
旋转子段 连60分都没想,考试一直肝t3,t2,没想到t1最简单 我一直以为t1很难,看了题解发现也就那样 题解 性质1 一个包含a[i]旋转区间值域范围最多为min(a[i],i)----max(a ...
- 883H - Palindromic Cut(思维+STL)
题目链接:http://codeforces.com/problemset/problem/883/H 题目大意:给一段长度为n的字符串s,想让你把s切成几段长度相同的回文串,可以改变s中字符的排列, ...
- HZOJ 旋转子段
作者的正解: 算法一:对于30%的数据: 直接枚举区间直接模拟,时间复杂度O(N3). 算法二:对于60%的数据:枚举旋转中心点,然后再枚举旋转的端点, 我们可以用O(n)的预处理求前缀和记录固定点, ...
- UVA1471-Defense Lines(思维+STL)
Problem UVA1471-Defense Lines Accept: 297 Submit: 2776Time Limit: 9000 mSec Problem Description Aft ...
- CodeForces - 988D(思维STL)
原文地址:https://blog.csdn.net/weixin_39453270/article/details/80548442 博主已经讲的很好了 题意: 从一个序列中,选出一个集合,使得集合 ...
- CSL 的字符串(思维+STL操作)
链接:https://ac.nowcoder.com/acm/contest/551/D 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语言1048 ...
- 【JZOJ6288】旋转子段
description analysis 可以先用前缀和把原串不调整的方案数先求出来 对于一种翻转,肯定是把\([i..a[i]]\)或\([a[i]..i]\)这段区间翻转 也可以看做是以\({i+ ...
随机推荐
- python模块:excel的读和修改xlrd/xultils
一.xlrd xlrd只能对excel进行读取,不可编辑修改.该模块属于第三方模块,需要安装模块包并引入.pip install xlrd 常用的方法: import xlrd book = xlrd ...
- 《Head First 设计模式》:组合模式
正文 一.定义 组合模式允许你将对象合成树形结构来表现"整体/部分"层次结构.组合能让客户以一致的方式处理组合对象以及个体对象. 组合对象:包含其他组件的组件. 个体对象(叶节点对 ...
- 云计算openstack——高可以负载均衡(14)
一.云平台概要 1.本openstack云平台使用开源软件Openstack Ocata版…… 2.OpenStack 部署环境中,各节点可以分为几类: Cloud Controller Node ( ...
- MATLAB 与 Excel 接口
MATLAB 与 Excel 接口MATLAB 与 Excel 有两种接口方式:一种是通过 MATLAB 提供的 Excel 生成器,生成220 MATLAB 实用教程DLL 组件和 VBA 代码,实 ...
- Mac使用Charles给iPhone抓包流程
目录 需求 步骤 1. Mac打开共享Wifi 2. iPhone连接刚刚的WIFI 3. 找到Mac的局域网ip 4. 配置代理 需求 有时候手机接口出问题了,不知道从哪里下手,Charles就是非 ...
- Spring学习(五)bean装配详解之 【XML方式配置】
一.配置Bean的方式及选择 配置方式 在 XML 文件中显式配置 在 Java 的接口和类中实现配置 隐式 Bean 的发现机制和自动装配原则 方式选择的原则 最优先:通过隐式 Bean 的发现机制 ...
- [GXYCTF2019]禁止套娃 1 &无参数RCE
[GXYCTF2019]禁止套娃 1 啥都没有那只能上扫描器来一探究竟了. 扫完没有啥结果,但网上找了一下说是git泄露,但是我这里显示了403. <?php include "fla ...
- 听说这四个概念,很多 Java 老手都说不清
Java 是很多人一直在用的编程语言,但是有些 Java 概念是非常难以理解的,哪怕是一些多年的老手,对某些 Java 概念也存在一些混淆和困惑. 所以,在这篇文章里,会介绍四个 Java 中最难理解 ...
- 基础篇:深入JMM内存模型解析volatile、synchronized的内存语义
目录 1 java内存模型,JMM(JAVA Memory Model) 2 CPU高速缓存.MESI协议 3 指令重排序和内存屏障指令 4 happen-before原则 5 synchronize ...
- Kafka索引设计的亮点
前言 其实这篇文章只是从Kafka索引入手,来讲述算法在工程上基于场景的灵活运用.单单是因为看源码的时候有感而写之. 索引的重要性 索引对于我们来说并不陌生,每一本书籍的目录就是索引在现实生活中的应用 ...