NOIP模拟测试29「爬山·学数数·七十和十七」
爬山题解不想写了
学数数
离散化然后找到以每一个值为最大值的连续子段有多少个,然后开个桶维护
那么怎么找以每一个值为最大值的连续子段个数
方法1(我的极笨的方法)
考试时我的丑陋思路,
定义极左值为左面第一个大于当前值的值,极右值为右面第一个大于当前值的值
,找到最大值然后当前符合的子段个数就为$r-l+1+(r-now)*(now-l)$
解释一下$r-l+1$为以$now$为边界的子段,$(r-now)*(now-l)$为包含$now$的子段
那么问题又转化为了如何求边界
我们发现找极左值,极右值过程可以二分实现,
我们每次找到最大值,然后找到左右子段的最大值和$id$,这些子段的最大值边界就是当前$now$!!!!
维护最大值$id$可以线段树实现
给一下实现
简单好想个屁嘞
但是比较直观是真的
void pre(ll l,ll r,ll now,ll nowmax){
if(l>r) return ;
if(l==r) {
sum[nowmax]++;
return ;
}
sum[nowmax]+=r-l+1+(r-now)*(now-l);
maxn=0,ida=0;
if(l<=now-1)
{
seg_max(1,l,now-1);
pre(l,now-1,ida,maxn);
}
maxn=0,ida=0;
if(now+1<=r)
{
seg_max(1,now+1,r);
pre(now+1,r,ida,maxn);
}
}
总代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 2222222
ll n,q,mx,mn=0x7fffffffff,ida,maxn,idb;
ll a[A],sum[A],b[A];
char c[10];
struct tree{
ll l,r,val,id;
}tr[A];
void pushup(ll p){
if(tr[p<<1].val>tr[p<<1|1].val){
tr[p].val=tr[p<<1].val;
tr[p].id=tr[p<<1].id;
}
else {
tr[p].val=tr[p<<1|1].val;
tr[p].id=tr[p<<1|1].id;
}
}
void built(ll p,ll l,ll r){
tr[p].l=l,tr[p].r=r;
if(l==r){
tr[p].val=a[l];
tr[p].id=l;
return ;
}
ll mid=(l+r)>>1;
built(p<<1,l,mid);
built(p<<1|1,mid+1,r);
pushup(p);
}
void seg_max(ll p,ll l,ll r){
// printf("p=%lld l=%lld r=%lld l=%lld r=%lld\n",p,l,r,tr[p].l,tr[p].r);
if(tr[p].l>=l&&tr[p].r<=r){
if(tr[p].val>maxn){
maxn=tr[p].val;
ida=tr[p].id;
}
return ;
}
ll mid=(tr[p].l+tr[p].r)>>1;
if(mid>=l)
seg_max(p<<1,l,r);
if(mid<r)
seg_max(p<<1|1,l,r);
}
void pre(ll l,ll r,ll now,ll nowmax){
if(l>r) return ;
if(l==r) {
sum[nowmax]++;
// printf("l=%lld nowmax=%lld \n",l,nowmax);
return ;
}
// printf("l=%lld r=%lld nowmax=%lld r-l=%lld\n",l,r,nowmax,r-l+1);
sum[nowmax]+=r-l+1+(r-now)*(now-l);
maxn=0,ida=0;
if(l<=now-1)
{
seg_max(1,l,now-1);
pre(l,now-1,ida,maxn);
}
maxn=0,ida=0;
if(now+1<=r)
{
seg_max(1,now+1,r);
pre(now+1,r,ida,maxn);
}
}
int main(){
scanf("%lld%lld",&n,&q);
for(ll i=1;i<=n;i++){
scanf("%lld",&a[i]);
b[i]=a[i];
if(a[i]>mx){
ida=i;
mx=a[i];
}
mn=min(mn,a[i]);
}
sort(b+1,b+n+1);
ll m=unique(b+1,b+n+1)-b-1;
// for(ll i=1;i<=m;i++){
// printf("b=%lld\n",b[i]);
// }
for(ll i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+1+m,a[i])-b;
built(1,1,n);
pre(1,n,ida,a[ida]);
for(ll i=1;i<=n;i++)
sum[i]+=sum[i-1];
for(ll i=1,que;i<=q;i++){
scanf("%s",c+1);
scanf("%lld",&que);
ll nxt=(lower_bound(b+1,b+m+1,que)-b),
pre=(upper_bound(b+1,b+m+1,que))-b-1;
// printf("pre=%lld nxt=%lld\n",pre,nxt);
if(c[1]=='<'){
if(que>mx){
printf("%lld\n",sum[n]);
continue ;
}
if(que<mn){
printf("0\n");
continue ;
}
if(pre!=nxt)
printf("%lld\n",sum[pre]);
else printf("%lld\n",sum[pre-1]);
}
else if(c[1]=='='){
if(que>mx||que<mn){
printf("0\n");
continue ;
}
if(pre==nxt)
printf("%lld\n",sum[pre]-sum[pre-1]);
else printf("0\n");
}
else if(c[1]=='>'){
if(que>mx){
printf("0\n");
continue ;
}
if(que<mn){
printf("%lld\n",sum[n]);
continue ;
}
if(pre==nxt)
printf("%lld\n",sum[n]-sum[pre]);
else printf("%lld\n",sum[n]-sum[pre]);
}
}
}
方法2
单调栈,显然可以单调栈,看到这个就必须想单调栈啊!
维护一个单调下降的栈当发现当前值比队尾小接着插,发现当前值不小$pop$,当前值的$l$就是$pop$后单调栈的栈顶,已经$pop$掉的值的$r$就是当前值
代码咕了
七十和十七
设$g[i]$为将相对大小为$i$的数插到队头要花多少步复原
注意是相对大小
以下说的1,2...都是相对大小
我们将$1$移到队头要$1$步复原,$g[1]=1$
将$2$移到队头你相对大小为$1$的也要复原$g[2]=g[1]+1$
将$3$移到队头你大小$1,2$也要复原$g[3]=g[2]+g[1]+1$
...类推
$g[n]=\sum\limits {i=1}^{i<=n-1}(g[i])+1$
然后我们设$f$为移动总步数
$f[i]=f[i-1](为1的情况)+\sum\limits_{j=1}^{j<=i-1} f[i-1]+(i-1)!*g[j]$
,最后再同时除以$i!$,为了方便我们设$E[i]=\frac{f[i]}{i!}$
原式变为$E[i]=E[i-1]+\frac{2^{i-1}-1}{i}$
我们化简移项等操作$xjb$搞就$AC$了
NOIP模拟测试29「爬山·学数数·七十和十七」的更多相关文章
- 8.22 NOIP模拟测试29(B) 爬山+学数数+七十和十七
T1 爬山 二分最高高度,$O(1)$判断是否可行. #include<iostream> #include<cstdio> #define ll long long usin ...
- NOIP模拟测试3「序列·熟练剖分·建造游乐园(play)」
---恢复内容开始--- 序列 刚调出来样例就A了,假装是水题. 因为是乱序,我们要求出来每两项之间最小公比,而不是直接比 求出来每两项之间最小公比,然后扫一遍就完了.(还要注意重复情况) 那么问题就 ...
- NOIP模拟测试19「count·dinner·chess」
反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...
- 20190803 NOIP模拟测试12「斐波那契(fibonacci)· 数颜色 · 分组 」
164分 rank11/64 这次考的不算太差,但是并没有多大的可能性反超(只比一小部分人高十几分而已),时间分配还是不均,T2两个半小时,T1半个小时,T3-额十几分钟吧 然额付出总是与回报成反比的 ...
- NOIP模拟测试10「大佬·辣鸡·模板」
大佬 显然假期望 我奇思妙想出了一个式子$f[i]=f[i-1]+\sum\limits_{j=1}^{j<=m} C_{k \times j}^{k}\times w[j]$ 然后一想不对得容 ...
- NOIP模拟测试29(A)
T1: 题目大意:有一张有向无环图,第$x$次经过边$i$的代价为$a_ix+b_i$,最多经过$c_i$次,起点为1,$s$个点可作为终点,求走$k$次的最小代价. 我们新建一个汇点,将所有可做为终 ...
- NOIP模拟测试38「金·斯诺·赤」
金 辗转相减见祖宗 高精 #include<bits/stdc++.h> using namespace std; #define A 2000 #define P 1 #define N ...
- NOIP模拟测试30「return·one·magic」
magic 题解 首先原式指数肯定会爆$long$ $long$ 首先根据欧拉定理我们可以将原式换成$N^{\sum\limits_{i=1}^{i<=N} [gcd(i,N)==1] C_{G ...
- NOIP模拟测试25「字符串·乌鸦喝水·所陀门王的宝藏(陀螺王)」
字符串 题解 没看出catalan怎么办 dp打表啊! 考虑大力dp拿到30分好成绩!顺便收获一张表 打表发现$C_{n+m}^{m}-C_{n+m}^{m-1}$ 仔细观察然后发现其实就是之前的网格 ...
随机推荐
- ConcurrentHashMap源码解读一
最近在学习并发map的源码,如果由错误欢迎指出.这仅供我自己学习记录使用. 首先就先来说一下几个全局变量 private static final int MAXIMUM_CAPACITY = 1 & ...
- 一句 Task.Result 就死锁, 这代码还怎么写?
一:背景 1. 讲故事 前些天把 .NET 高级调试 方面的文章索引到 github 的过程中,发现了一个有意思的评论,详见 文章,截图如下: 大概就是说在 Winform 的主线程下执行 Task. ...
- SAP ABAP ALV 颜色设置(两个ALV函数例子) 列 行 单元格
@[TOC](设置ALV颜色)# 前言淦! 要求花花绿绿的ALV ,那就淦他! 需要的参数和对应颜色放在最后.稍微改改就能用. 介绍两个常用的ALV函数实现1.REUSE_ALV_GRID_DISPL ...
- MFC Object 与 Windows Object
MFC Object 和 Windows Object的含义 Window Object(Window对象)是Win32下用句柄表示的Windows操作系统对象.MFC Object(MFC对象)是C ...
- 2020BUAA-个人博客-案例分析
个人博客作业-软件案例分析 项目 内容 北航2020软工 班级博客 作业要求 具体要求 我的课程目标 通过案例分析提升自己对于软件工程的认识 课程收获 分析软件,了解软件的定位 第一部分 调研,评测( ...
- 解决nohup: 忽略输入并把输出追加到"nohup.out"或者nohup: 忽略输入重定向错误到标准输出端
nohup启动脚本的时候,没有指定输出路径,默认使用当前目录的nohup.out 例如下面这句就是默认使用nohup.out作为输出文件: nohup script.sh & 改成下面的,则/ ...
- Linux_防火墙与SElinux
一.防火墙与SElinux 1.防火墙和selinux 防火墙 iptables 默认允许所以 firewalld 默认拒绝所有 ebtables 不认识,不管 se ...
- 记一次MySQL(5.7版本)数据库的主从同步和备份
我遇到的问题 我先后在BAT三大云服务器商购买了学生机,配置如下 百度云2核/4G 阿里云1核/2G 腾讯云1核/2G 我的解决方案 由于我不知道百度云的续费规则,导致买了2核/4G的服务器之后以为像 ...
- python基础之进程、线程、协程篇
一.多任务(多线程) 多线程特点:(1)线程的并发是利用cpu上下文的切换(是并发,不是并行)(2)多线程执行的顺序是无序的(3)多线程共享全局变量(4)线程是继承在进程里的,没有进程就没有线程(5) ...
- S6 文件备份与压缩命令
6.1 tar:打包备份 6.2 gzip:压缩或解压文件 6.3-4 zip.unzip 6.5 scp:远程文件复制 6.6 rsync:文件同步工具