A. 打表

首先注意这道题数组下标从 \(0\) 开始

可以找规律发现是 \(\displaystyle\frac{\sum |a_i-a _ {ans}|}{2^k}\)

那么严谨证明一下:

由于两个 \(CPU\) 的种类是等概率的,而选择为最优选择,那么每一位的枚举顺序是没有影响的。对于每一位来说,一个选了 \(0\) 的情况,相应地另一个就是 \(1\) 的情况,所以对于所有的情况总和是绝对值之差

对于这类期望题,还是大胆猜结论比较靠谱……


B. 蛇

由于格子特殊的形状,蛇的行动路线一定是往左走一截再从另一行走回来,然后 \(S\) 型盘旋,最后往右走一段再走回来。

那么左右两段可以用哈希直接判断,而中间部分由于横向移动方向单调可以进行 \(dp\)

设 \(f[k][i][j]\) 表示第 \(k\) 行第 \(i\) 列,匹配到模式串第 \(j\) 位的方案数

为避免环形转移,令当前列只能从上一列转移过来

\(hash\) 特别容易出错,需要处理前缀和后缀两种哈希

代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=4005;
const int mod=1e9+7,base=131;
int n,m,pash[3][maxn],sash[3][maxn],hash1[maxn],bash[maxn],po[maxn],ans,f[3][maxn/2][maxn];
char a[3][maxn/2],b[maxn];
void solve(){
memset(f,0,sizeof f);
memset(pash,0,sizeof pash);
memset(sash,0,sizeof sash);
for(int i=1;i<=2;i++){
for(int j=1;j<=n;j++)pash[i][j]=(pash[i][j-1]*base+a[i][j])%mod;
for(int j=n;j>=1;j--)sash[i][j]=(sash[i][j+1]*base+a[i][j])%mod;
}
// cout<<"ppp "<<pash[1][2]<<" "<<sash[2][3]<<endl;
for(int k=1;k<=2;k++){
for(int i=1;i<=n;i++){
if(a[k][i]==b[1])f[k][i][1]=1;
for(int j=i;j<=n;j++){
int len=j-i+1;
if(len*2>m)continue;
int sum=((pash[k][j]-pash[k][i-1]*po[len]%mod+mod)%mod+(sash[3-k][i]-sash[3-k][j+1]*po[len]%mod+mod)%mod*po[len]%mod)%mod;
sum=(sum+mod)%mod;
int sum1=(bash[1]-bash[len*2+1]*po[len*2]%mod)%mod;
sum1=(sum1+mod)%mod;
// if(k==1&&i==2&&j==2)cout<<sum<<" "<<sum1<<" "<<bash[1]<<" "<<bash[len*2+1]<<" "<<po[m-len*2]<<endl;
if(sum1==sum){
// cout<<"hhhh "<<k<<" "<<i<<" "<<j<<" "<<len*2<<endl;
f[3-k][j][len*2]=1;
}
}
}
}
// cout<<f[1][5][4]<<endl;
for(int i=2;i<=n;i++){
for(int j=2;j<=m;j++){
for(int k=1;k<=2;k++){
if(a[k][i]==b[j]){
f[k][i][j]=(f[k][i][j]+f[k][i-1][j-1])%mod;
// if(k==1&&i==5&&j==4)cout<<f[k][i][j]<<" "<<f[k][i-1][j-1]<<endl;
if(a[3-k][i]==b[j-1]&&j>=2)f[k][i][j]=(f[k][i][j]+f[3-k][i-1][j-2])%mod;
}
}
}
}
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// for(int k=1;k<=2;k++){
// if(f[k][i][j])cout<<k<<" "<<i<<" "<<j<<" "<<f[k][i][j]<<endl;
// }
// }
// }
for(int k=1;k<=2;k++){
for(int i=1;i<=n;i++){
// if(f[k][i][m]){
// cout<<"kkk "<<k<<" "<<i<<" "<<f[k][i][m]<<endl;
// }
ans=(ans+f[k][i][m])%mod;
for(int j=i+1;j<=n;j++){
int len=j-i+1;
if(len*2>m)continue;
int sum=((pash[k][j]-pash[k][i-1]*po[len]%mod+mod)%mod*po[len]%mod+(sash[3-k][i]-sash[3-k][j+1]*po[len]%mod+mod)%mod)%mod;
sum=(sum+mod)%mod;
int sum1=(hash1[m]-hash1[m-len*2]*po[len*2]%mod)%mod;
sum1=(sum1+mod)%mod;
// if(i==4&&j==5&&k==2)cout<<sum<<" "<<sum1<<endl;
if(sum==sum1){
// cout<<k<<" "<<i<<" "<<j<<endl;
// if(f[k][i-1][m-len*2]){
// cout<<3-k<<" "<<i-1<<" "<<m-len*2<<" "<<f[3-k][i-1][m-len*2]<<endl;
// }
ans=(ans+f[k][i-1][m-len*2])%mod;
}
}
}
}
return ;
}
void pre(){
po[0]=1;
for(int i=1;i<=2000;i++){
po[i]=po[i-1]*base%mod;
}
for(int i=1;i<=m;i++)hash1[i]=(hash1[i-1]*base+b[i])%mod;
for(int i=m;i>=1;i--)bash[i]=(bash[i+1]*base+b[i])%mod;//,cout<<bash[i]<<" ";
// cout<<endl;
return ;
}
bool vis[3][maxn];
int movx[5]={0,1,0,-1};
int movy[5]={1,0,-1,0};
bool pd(int x,int y){
return x>=1&&y>=1&&x<=2&&y<=n;
}
void dfs(int x,int y,int len){
// cout<<x<<" "<<y<<" "<<len<<endl;
if(len==m){
ans++;
return ;
}
vis[x][y]=true;
for(int i=0;i<4;i++){
int xx=x+movx[i];
int yy=y+movy[i];
if(vis[xx][yy])continue;
if(pd(xx,yy)){
if(a[xx][yy]==b[len+1]){
dfs(xx,yy,len+1);
}
}
}
vis[x][y]=false;
return ;
}
signed main(){
// freopen("shuju.in","r",stdin);
cin>>n;
scanf("%s",a[1]+1);
scanf("%s",a[2]+1);
n=strlen(a[1]+1);
scanf("%s",b+1);
m=strlen(b+1);
if(m<=2){
for(int i=1;i<=2;i++){
for(int j=1;j<=n;j++){
if(a[i][j]==b[1])dfs(i,j,1);
}
}
cout<<ans;
return 0;
}
pre();
solve();
// cout<<ans<<endl;
reverse(a[1]+1,a[1]+n+1);
reverse(a[2]+1,a[2]+n+1);
solve();
cout<<ans;
return 0;
}

C. 购物

对于一个特定的体积 \(x\),能更新的满足条件的 \(k\) 集合为 \([\left \lceil \frac{x}{2}\right \rceil ,x]\)

那么发现这样的区间大多都是连续的,除非出现这样的情况:

将所有物品从小到大排好序,那么如果 \(a_i>2 * sum_{i-1}\),中间的一段是空下的,因为后面的体积更大,无法补充空隙

所以没加入一个数进行判断即可

代码实现
#include<bits/stdc++.h>
using namespace std;
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
#define int long long
const int maxn=1e5+5;
int n,a[maxn],ans,sum;
signed main(){
n=read();
for(int i=1;i<=n;i++)a[i]=read();
sort(a+1,a+n+1);
int rp=0;
for(int i=1;i<=n;i++){
rp=max((a[i]+1)>>1,sum+1);
sum+=a[i];
ans+=sum-rp+1;
}
cout<<ans;
return 0;
}

D. ants

发现这道题插入很容易但是删除对答案的贡献并不确定

于是引入新科技——回滚莫队

这种莫队方式块内每个询问都直接把左端点拽回块右端点并恢复历史版本,往左移动,这样可以保证只有加操作了

复杂度不变还是根号的

代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+5;
int n,m,size,be[maxn],le[maxn],ri[maxn],l,r,tp,now,len,b[maxn],a[maxn],cnt,mx,ans[maxn];
bool vis[maxn];
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
struct Node{
int l,r,id;
Node(){}
Node(int x,int y,int z):l(x),r(y),id(z){}
}ask[maxn];
struct Rec{
int p,v,l,r;
Rec(){}
Rec(int x,int y,int z,int w):p(x),v(y),l(z),r(w){}
}sta[maxn];
bool cmp(Node a,Node b){
return be[a.l]==be[b.l]?a.r<b.r:a.l<b.l;
}
void push(int x){
sta[++tp]=Rec(x,vis[x],le[x],ri[x]);
return ;
}
void add(int x,bool op){
int l=le[x-1],r=ri[x+1];
if(vis[x-1]){
if(op)push(l);
}
else l=x;
if(vis[x+1]){
if(op)push(r);
}
else r=x;
if(op)push(x);
vis[x]=true,le[x]=l,ri[x]=r,ri[l]=r,le[r]=l;
now=max(now,ri[x]-le[x]+1);
return ;
}
void clear(){
while(tp){
Rec x=sta[tp--];
vis[x.p]=x.v,le[x.p]=x.l,ri[x.p]=x.r;
}
return ;
}
int baoli(int l,int r){
for(int i=l;i<=r;i++)add(a[i],1);
int res=now;
now=0;
clear();
return res;
}
int main(){
n=read();
m=read();
size=sqrt(n);
for(int i=1;i<=n;i++)a[i]=read(),be[i]=(i-1)/size+1,le[i]=ri[i]=i;
for(int i=1;i<=m;i++){
l=read();
r=read();
if(be[l]==be[r])ans[i]=baoli(l,r);
else ask[++cnt]=Node(l,r,i);
}
sort(ask+1,ask+cnt+1,cmp);
for(int i=1;i<=cnt;i++){
if(be[ask[i].l]!=be[ask[i-1].l]){
now=0;
r=size*be[ask[i].l];
for(int j=1;j<=n;j++)vis[j]=0,le[j]=ri[j]=j;
}
while(r<ask[i].r)add(a[++r],0);
int l=size*be[ask[i].l]+1,last=now;
while(l>ask[i].l)add(a[--l],1);
ans[ask[i].id]=now;
now=last,clear();
}
for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
return 0;
}

noip模拟45的更多相关文章

  1. noip模拟45[真是啥也不会]

    noip模拟45 solutions 真是一个题都不会了,然而考完试之后我在10min之内切掉了最后一个题 话说这是为什么呢, 因为最后一个是回滚莫队的大板子,然而我忘记了,不不不,是没有记起来过 T ...

  2. Noip模拟45 2021.8.21

    一定别删大括号,检查是;还是, ceil函数里面要写double,否则根本没用!!!!!!! T1 打表 正解:打表 考场上很难真正把柿子理解着推出来 况且想要理解题意就很难,比如我就理解错了 半猜着 ...

  3. 2021.8.21考试总结[NOIP模拟45]

    T1 打表 由归纳法可以发现其实就是所有情况的总和. $\frac{\sum_{j=1}^{1<<k}(v_j-v_{ans})}{2^k}$ $code:$ 1 #include< ...

  4. [考试总结]noip模拟45

    真开心,挂没了.. 考完:"你们怎么第二题打了这么点分,明明一个爆搜就有65pts!!!怎么跟别人打?!" 然后我看了看我的爆搜,30pts. 然后认为自己打爆了... 我又想为什 ...

  5. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  6. 2019.7.29 NOIP模拟测试10 反思总结【T2补全】

    这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...

  7. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥

  8. NOIP 模拟4 T2

    本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...

  9. noip模拟31[time·game·cover]

    noip模拟31 solutions 我就觉得这些考试题是越考越难,我是也越考越完蛋,已经完完全全的接近爆零了 只有20pts,说真的这还是我第一次挂掉30pts,本来我还有50pts嘞 所以这次考试 ...

随机推荐

  1. Vue单点登录控件代码分享

    这里提供一个Vue单点登录的demo给大家参考,希望对想了解的朋友有一些帮助. 具体的原理大家可以查看我的上篇文章 vue实现单点登录的N种方式 废话不多少直接上代码 这里分两套系统,一是登录系统的主 ...

  2. Centos8 Nginx 开机自启配

    第一步:创建 service文件 vim /lib/systemd/system/nginx.service /lib 与 /usr/lib 我这里配置时是一样的,在那个文件夹配置都可以 第二步:编写 ...

  3. 给每个li延时添加样式动画效果(setInterval,clearInterval)

    btnsAnime($('ul li')) function btnsAnime(pagesl) { var that = this $(pagesl).hide() let i = 0; funct ...

  4. Js实现随机某个li样式增加

    一.首先引入jquery  cdn   二.基础样式 三.目的 为了使随机某个li背后有个旋转的图片 四.核心代码 html代码: <div class="bg3"> ...

  5. 从理发店小弟到阿里P10大牛,一位高中学渣的“登天”之路

    蚂蚁金服,可能是众多程序猿眼中梦寐以求的归宿,无数拿过数不清奖状的各个高校走出的学子精英都挤破头皮,只为能在蚂蚁占有一席之地. 蚂蚁金服里不乏各种深藏不露的大佬,到了那里才会深刻明白一山还有一山高这句 ...

  6. Prettier-Code Formater代码格式化插件使用教程

    目录 Prettier-Code Formater代码格式化插件使用教程 插件的安装 插件的使用 方式一: 配置VScode代码格式化后, 结合VScode快捷键使用 方式二: CLI中使用命令行的方 ...

  7. Eclipse的XML编辑器解决方案

    现在使用的Eclipse SDK 3.7.2里没有XML编辑器,无法进行语法高亮,也没有格式化(按层次控制缩进量)和设计视图,很不方便.对于ant文件,可以用Ant Editor来打开,ivy文件在装 ...

  8. Shell-12-linux信号

    信号类型 信号:信号是在软件层次上对中断机制的一种模拟,通过给一个进程发送信号,执行相应的处理函数 进程可以通过三种方式来响应一个信号: 1.忽略信号,即对信号不做任何处理,其中有两个信号不能忽略: ...

  9. STM32—ADC详解

    文章目录 一.ADC简介 二.ADC功能框图讲解 1.电压输入范围 2.输入通道 3.转换顺序 4.触发源 5.转换时间 6.数据寄存器 7.中断 8.电压转换 三.初始化结构体 四.单通道电压采集 ...

  10. 题解 P3158 [CQOI2011]放棋子

    题解 本题是一个 \(DP\) 加 容斥,容斥的式子很好推,重点是如何想到和如何推出 \(DP\) 部分的式子. 因为不同种颜色的棋子不能放在同一行或同一列,所以不同种的棋子是相对独立的. 据此,我们 ...