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. ClickHouse入门笔记

    ClickHouse笔记 目录 ClickHouse笔记 第 1 章 ClickHouse 入门 列式储存的好处: 第 2 章 ClickHouse 的安装 第 3 章 数据类型 整型 浮点型 布尔型 ...

  2. GoogleTest死亡测试的跨平台BUG

    最近工作用到了GoogleTest来作单元测试,但是死亡测试的ASSERT_DEATH语句一直跑不通. GoogleTest会启动子进程来运行代码,并捕捉子进程的错误消息,这就是所谓的"死亡 ...

  3. Sqlserver 关于varchar(max) 笔记

    看SQL server的版本,SQLserver2005以上 的nvarchar(max) 可以存放2G的内容,所以要是 SQL2005以上的nvarchar(max)足够你用的了.用nvarchar ...

  4. 作为Java开发工程师,如何高效优雅地编写接口文档

    作为一名优秀的Java开发工程师,编写接口文档向来是一件很头疼的事情.本来就被bug纠缠的很累了,你还让我干这? 其实,你可以试试ApiPost. ApiPost的定位是Postman+Swagger ...

  5. Cobaltstrike与MSF会话派生

    Cobaltstrike与MSF会话派生 前言 一般在渗透的过程中,Get到shell之后一般来说我喜欢上线到Cobaltstrike,但是Cobaltstrike的会话是60S更新一次,有时候功能也 ...

  6. RHCSA_DAY04

    软连接与硬连接 Linux中的链接文件类似于windows中的快捷方式 软连接特点:软连接可以跨分区,可以对目录进行链接,源文件删除后,链接文件不可用 软连接命令格式:ln -s 源文件路径  目标路 ...

  7. 文件上传之WAF绕过及相安全防护

    文件上传在数据包中可修改的地方 Content-Disposition:一般可更改 name:表单参数值,不能更改 filename:文件名,可以更改 Content-Type:文件 MIME,视情况 ...

  8. Android NDK/JIN 从入门到精通

    1.1 JNI(Java Native Interface) 提供一种Java字节码调用C/C++的解决方案,JNI描述的是一种技术 1.2 NDK(Native Development Kit) A ...

  9. 代码中如何优化过多的if..else

    针对代码中,过多的  if ... else ..,如何优化减少if else呢?(非常重要的优化技巧) 缺点:过多的if else 导致阅读不方便,逻辑过于复杂,代码多长. 解决方法:可以采用多个方 ...

  10. Install Redmine Server with Bitnami Installer

    Download bitnami installer: bitnami-redmine-2.4.1-1-linux-installer.run $ chmod 755 bitnami...instal ...