noip模拟45[真是啥也不会]
noip模拟45 solutions
真是一个题都不会了,然而考完试之后我在10min之内切掉了最后一个题
话说这是为什么呢,
因为最后一个是回滚莫队的大板子,然而我忘记了,不不不,是没有记起来过
T1 打表
好像还真的是一个打表题,找找规律就能过,真的
结论就是
\(\huge res=\frac{\sum\limits^{n}_{i=1}abs(x_i-x_{ans})}{2^k}\)
这个是可以证出来的,
首先对于只剩下一位没有选的时候,肯定是一个CPU选1,另外一个选0
我们考虑剩下更多的情况,可以知道每次两个CPU都会选择同一位进行操作,并选择不同的数
所以期望仍然是一半一半,所以还是剩下的数的差的平均数
AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
const int N=1<<18;
const ll mod=1e9+7;
ll k,ans,a[N],res;
ll ksm(ll x,ll y){
ll ret=1;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;
y>>=1;
}
return ret;
}
signed main(){
scanf("%lld%lld",&k,&ans);
for(re i=0;i<(1<<k);i++)scanf("%lld",&a[i]);
ans=a[ans];
for(re i=0;i<(1<<k);i++)res=(res+abs(a[i]-ans))%mod;
printf("%lld",res*ksm(ksm(2ll,k),mod-2)%mod);
}
其实考场上没有看懂题,还找人讲了一下
T2 蛇
好象是CF的原题,我也没做过,暴搜还打错了,不知道为啥,不打了,直接正解
肯定是扭来扭去的走的,最后接上两个平着的

那我们就设dp[i][j][k][0/1]表示在第i行,第j列,匹配到了第k个字符
0表示可以竖着转移,1表示不可以
我们直接枚举下一个字符,转移就行了
前面的那个横着的直接预处理就好了,后面的等到dp完了之后再处理
这个处理就用hash就行了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ull unsigned long long
#define ll long long
const ull bas=131;
const int N=2005;
const ll mod=1e9+7;
ll n,m,dp[2][N][N][2],ans;
char ch[2][N],a[N];
ull hc[2][2][N],ha[N],ba[N];
ull get_hc0(int x,int l,int r){return hc[x][0][r]-hc[x][0][l-1]*ba[r-l+1];}
ull get_hc1(int x,int l,int r){return hc[x][1][l]-hc[x][1][r+1]*ba[r-l+1];}
ull get_ha(int l,int r){return ha[r]-ha[l-1]*ba[r-l+1];}
void get_ans(){
memset(dp,0,sizeof(dp));
for(re i=0;i<=1;i++)for(re j=1;j<=n;j++)hc[i][0][j]=hc[i][0][j-1]*bas+ch[i][j]-'a';
for(re i=0;i<=1;i++)for(re j=n;j>=1;j--)hc[i][1][j]=hc[i][1][j+1]*bas+ch[i][j]-'a';
for(re i=0;i<=1;i++)for(re j=1;j<=n;j++){
dp[i][j][1][0]=(ch[i][j]==a[1]);
for(re k=2;k<=j;k++)
if((k<<1)<=m)dp[i][j][k<<1][1]=(get_hc0(i,j-k+1,j)==get_ha(k+1,k<<1)&&get_hc1(i^1,j-k+1,j)==get_ha(1,k));
}
for(re k=1;k<=m;k++)for(re i=0;i<=1;i++)for(re j=1;j<=n;j++){
if(ch[i][j]!=a[k])continue;
dp[i][j][k][0]=(dp[i][j][k][0]+dp[i][j-1][k-1][0]+dp[i][j-1][k-1][1])%mod;
dp[i][j][k][1]=(dp[i][j][k][1]+dp[i^1][j][k-1][0])%mod;
}
for(re i=0;i<=1;i++)for(re j=1;j<=n;j++)for(re k=0;k<=m;k++){
if((m-k)&1)continue;
if(m-k==2)continue;
int mid=m-k>>1;
if(m!=k&&(j+mid>n||get_hc0(i,j+1,j+mid)!=get_ha(k+1,k+mid)||get_hc1(i^1,j+1,j+mid)!=get_ha(k+mid+1,m)))continue;
ans=(ans+dp[i][j][k][0]+dp[i][j][k][1])%mod;
}
}
signed main(){
scanf("%s",ch[0]+1);scanf("%s",ch[1]+1);n=strlen(ch[0]+1);
scanf("%s",a+1);m=strlen(a+1);ba[0]=1;
for(re i=1;i<=m;i++)ba[i]=ba[i-1]*bas,ha[i]=ha[i-1]*bas+a[i]-'a';
get_ans();
reverse(ch[0]+1,ch[0]+n+1);
reverse(ch[1]+1,ch[1]+n+1);
get_ans();
if(m==1)for(re i=0;i<=1;i++)for(re j=1;j<=n;j++)ans=(ans-(ch[i][j]==a[1])+mod)%mod;
if(m==2)for(re i=0;i<=1;i++)for(re j=1;j<=n;j++)ans=(ans+mod-(ch[i][j]==a[1]&&ch[i^1][j]==a[2]))%mod;
printf("%lld",ans);
}
T3 购物
这个说白了也是一个结论题,我还是不会
结论:我们在K的覆盖轴上,可能出现空缺的点一定在i-1的前缀和与\(\frac{x_i}{2}\)之间
我们证明这个结论:
我们现在不在乎i-1之前如何,我们之在乎i这个数,
设\(sum_i\)为前i个数的和,\(x_i\)为第i个数,我们按照\(x_i\)从小到大排序
如果在\(sum_{i-1}\)和\(\frac{x_i}{2}\)之间出现了没有覆盖的点,
因为后面的点都比\(x_i\)大,所以没有点可以填补这个空缺
还要证明\(\frac{x_i}{2}-sum_i\)这个区间是连续的
首先\(sum_i=sum_{i-1}+x_i\)那么\(\frac{sum_i}{2}\le\max(x_i,sum_{i-1})\)
所以这样的区间一定可以接上。
AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
const int N=1e5+5;
ll n,a[N],sum[N],rec;
signed main(){
scanf("%lld",&n);
for(re i=1;i<=n;i++)scanf("%lld",&a[i]);
sort(a+1,a+n+1);
for(re i=1;i<=n;i++){
rec+=((a[i]+1)/2-sum[i-1]-1>0?(a[i]+1)/2-sum[i-1]-1:0);
sum[i]=sum[i-1]+a[i];
}
printf("%lld",sum[n]-rec);
}
T4 ants
题面翻译:给定l,r,求[l,r]区间内的数的最长连续段
回滚莫队大板子。。。
AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
const int N=100005;
int n,m;
int c[N],pos[N],di;
int ans[N];
int lb[N],rb[N];
struct query{
int l,r,id,p;
}qus[N];
struct front{
int typ,p,val;
}fro[N];
inline bool comp(query x,query y){
if(pos[x.l]==pos[y.l])
return x.r<y.r;
return x.l<y.l;
}
int main(){
scanf("%d%d",&n,&m);
di=sqrt(n);
for(re i=1;i<=n;i++){
scanf("%d",&c[i]);
pos[i]=i/di+1;
}
for(re i=1;i<=m;i++){
scanf("%d%d",&qus[i].l,&qus[i].r);
qus[i].id=i;
qus[i].p=pos[qus[i].l];
}
sort(qus+1,qus+m+1,comp);
int r,sum,res,tmp;
for(re i=1;i<=m;i++){
if(qus[i].p!=qus[i-1].p){
sum=0;
for(re j=1;j<=n;j++)
lb[j]=rb[j]=0;
r=qus[i].p*di;
}
while(r<qus[i].r){
r++;
lb[c[r]]=lb[c[r]-1]+1;
rb[c[r]]=rb[c[r]+1]+1;
tmp=lb[c[r]]+rb[c[r]]-1;
sum=max(sum,tmp);
lb[c[r]+rb[c[r]]-1]=tmp;
rb[c[r]-lb[c[r]]+1]=tmp;
}
res=sum;
int s=0;
for(re l=qus[i].l;l<=min(qus[i].r,qus[i].p*di);l++){
lb[c[l]]=lb[c[l]-1]+1;
rb[c[l]]=rb[c[l]+1]+1;
tmp=lb[c[l]]+rb[c[l]]-1;
res=max(res,tmp);
fro[++s].typ=1;fro[s].p=c[l]+rb[c[l]]-1;fro[s].val=lb[c[l]+rb[c[l]]-1];
fro[++s].typ=2;fro[s].p=c[l]-lb[c[l]]+1;fro[s].val=rb[c[l]-lb[c[l]]+1];
lb[c[l]+rb[c[l]]-1]=tmp;
rb[c[l]-lb[c[l]]+1]=tmp;
}
ans[qus[i].id]=res;
for(re j=s;j>=1;j--){
if(fro[j].typ==1)
lb[fro[j].p]=fro[j].val;
else
rb[fro[j].p]=fro[j].val;
}
for(re j=qus[i].l;j<=min(qus[i].r,qus[i].p*di);j++){
lb[c[j]]=rb[c[j]]=0;
}
}
for(re i=1;i<=m;i++){
printf("%d\n",ans[i]);
}
}
noip模拟45[真是啥也不会]的更多相关文章
- Noip模拟45 2021.8.21
一定别删大括号,检查是;还是, ceil函数里面要写double,否则根本没用!!!!!!! T1 打表 正解:打表 考场上很难真正把柿子理解着推出来 况且想要理解题意就很难,比如我就理解错了 半猜着 ...
- 2021.8.21考试总结[NOIP模拟45]
T1 打表 由归纳法可以发现其实就是所有情况的总和. $\frac{\sum_{j=1}^{1<<k}(v_j-v_{ans})}{2^k}$ $code:$ 1 #include< ...
- noip模拟45
A. 打表 首先注意这道题数组下标从 \(0\) 开始 可以找规律发现是 \(\displaystyle\frac{\sum |a_i-a _ {ans}|}{2^k}\) 那么严谨证明一下: 由于两 ...
- [考试总结]noip模拟45
真开心,挂没了.. 考完:"你们怎么第二题打了这么点分,明明一个爆搜就有65pts!!!怎么跟别人打?!" 然后我看了看我的爆搜,30pts. 然后认为自己打爆了... 我又想为什 ...
- NOIP模拟 1
NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. # 用 户 名 ...
- 2019.7.29 NOIP模拟测试10 反思总结【T2补全】
这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...
- NOIP模拟17.9.22
NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥
- NOIP 模拟4 T2
本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...
- noip模拟31[time·game·cover]
noip模拟31 solutions 我就觉得这些考试题是越考越难,我是也越考越完蛋,已经完完全全的接近爆零了 只有20pts,说真的这还是我第一次挂掉30pts,本来我还有50pts嘞 所以这次考试 ...
随机推荐
- 8 shell if else
if 语句的判断条件,从本质上讲,判断的就是命令的退出状态. 语句 语句格式 同一行书写 注意点 用例1 用例2 if 语句 if conditionthen statement(s)fi if ...
- NodeJS 进程是如何退出的
有几种因素可以导致 NodeJS 进程退出.在这些因素中,有些是可预防的,比如代码抛出了一个异常:有些是不可预防的,比如内存耗尽.process 这个全局变量是一个 Event Emitter 实例, ...
- 整理C#获取日期显示格式
C#获取当前日期的几种显示格式 有时候需要用一些不常用的日期格式时,总是要去网上查找,很多都是复制粘贴,还不完整.就整理一下. DatetimeTextBox.Text += DateTime.Now ...
- 前端-Vue基础2
1.过滤器 前台通过后台传值,要对后台传过来的变量进行特殊处理,比如根据id转成中文等: 1.1 局部过滤器 局部过滤器只针对一个Vue实例 默认将|左侧count传递给右侧方法 {{count|fi ...
- Linux磁盘配额与LVM
一.LVM概述 逻辑卷管理 Logical Volume Manager二.LVM机制的基本概念三.LVM的管理命令 ① 主要命令 ② ==LVM逻辑卷操作流程== ③ 举例四.磁盘配额概述 ...
- Linux必备命令 - 常用命令集
默认进入系统,我们会看到这样的字符: [root@localhost ~]#,其中#代表当前是root用户登录,如果是$表示当前为普通用户.cd 命令 cd /home :解析:进入/home目录 ...
- C语言:虚拟地址 和编译模式
所谓虚拟地址空间,就是程序可以使用的虚拟地址的有效范围.虚拟地址和物理地址的映射关系由操作系统决定,相应地,虚拟地址空间的大小也由操作系统决定,但还会受到编译模式的影响.这节我们先讲解CPU,再讲解编 ...
- java面向对象程序设计(下)-枚举类
在某些情况下,一个类的对象是有限而且固定的,比如季节类,它只有4个对象;再比如行星类,目前只有8个对象,这些实例有限而且固定的类,在Java中被称为枚举类 JDK1.5新增了一个enum关键字,(它与 ...
- 使用ThinkPHP5.0.12连接Mongo数据库的经验
本地开发环境xamppv3.2.2,ThinkPHP5.0.12版本. 由于之前开发项目时使用的是TP3.2.3+mongo数据库,也是在本地进行的,所以也进行过mongo数据库驱动的配置.详细方法可 ...
- 【洛谷P1962 斐波那契数列】矩阵快速幂+数学推导
来提供两个正确的做法: 斐波那契数列双倍项的做法(附加证明) 矩阵快速幂 一.双倍项做法 在偶然之中,在百度中翻到了有关于斐波那契数列的词条(传送门),那么我们可以发现一个这个规律$ \frac{F_ ...