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. 🔥 LeetCode 热题 HOT 100(1-10)

    1. 两数之和 思路一:暴力遍历所有组合 class Solution { public int[] twoSum(int[] nums, int target) { for (int i = 0; ...

  2. noip模拟测试31

    终于有时间写博客了,前面一直咕咕咕都快变成一只公鸡了......这次考试,真的很意外,我在考场上觉得自己打出了T1的正解,样例一拍就过,还跑得嘎嘎快,然后T2,T3码了两个暴力,觉得自己应该能100p ...

  3. C语言运算符(关系运算符)+(逻辑运算符)

    下表显示了 C 语言支持的所有关系运算符.假设变量 A 的值为 10,变量 B 的值为 20,则: 实列: 1 #include <stdio.h> 2 3 int main() 4 { ...

  4. 谷歌内部流出Jetpack Compose最全上手指南,含项目实战演练!

    简介 Jetpack Compose是在2019Google i/O大会上发布的新的库.Compose库是用响应式编程的方式对View进行构建,可以用更少更直观的代码,更强大的功能,能提高开发速度. ...

  5. 【LeetCode】316. 去除重复字母

    316. 去除重复字母 知识点:栈:单调 题目描述 给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次.需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置). 示例 输 ...

  6. 说说 VARCHAR 背后的那些事

    在使用MySQL的过程中,在存储字符串时,大家或许都有过这样或那样的困惑,譬如: 1.  对于固定长度的字符串,为什么推荐使用 CHAR 来存储? 2.  VARCHAR 可设置的最大长度是多少? 3 ...

  7. Java8新特性(一)之Lambda表达式

    .personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...

  8. React脚手架配置代理

    react脚手架配置代理 方法一 在package.json中追加如下配置 "proxy":"http://localhost:5000" 说明: 优点:配置简 ...

  9. STM32—重定向printf和getchar函数到串口

    在STM32测试串口的时候经常需要在开发板和上位机之间传输数据,我们可以用c语言中的printf()函数和getchar()函数来简化传输. 以printf()为例: printf()函数实际上是一个 ...

  10. 见微知著 带你透过内存看 Slice 和 Array的异同

    hi, 大家好,我是 hhf. 有这么一个 Go 面试题:请说出 slice 和 array 的区别? 这简直就是送分题.现在思考一下,你咋样回答才能让面试官满意呢? 我这里就不贴这道题的答案了.但是 ...