多校A层冲刺NOIP2024模拟赛24

多校A层冲刺NOIP2024模拟赛24

\(T1\) A. 选取字符串 \(100pts\)

  • 考虑建出失配树,然后等价于询问 \(\sum\limits_{S \sube \{ 0,1,2, \dots ,n \},|S|=k}dep_{\operatorname{LCA}\{ S \}}^{2}\)

  • 不妨从 \(\operatorname{LCA}\) 的角度考虑,统计 \(x\) 能作为多少个 \(|S|\)\(\operatorname{LCA}\) 。但是这也不可做,考虑 \(x\) 对答案的贡献。

  • 同 luogu P5305 [GXOI/GZOI2019] 旧词 ,将单个点深度平方的贡献 \(dep_{x}^{2}\) 差分成路径上所有点深度的贡献 \(\sum\limits_{i \in (0 \to x)}(dep_{i}^{2}-dep_{fa_{i}}^{2})=\sum\limits_{i \in (0 \to x)}(2dep_{i}-1)\) ,再乘以 \(\dbinom{siz_{x}}{k}\) 即可。

  • \(\sum\limits_{i=0}^{n}(2dep_{i}-1)\dbinom{siz_{i}}{k}\) 即为所求。

    点击查看代码
    const ll p=998244353;
    ll siz[1000010],dep[1000010],nxt[1000010],jc[1000010],inv[1000010],jc_inv[1000010],ans=0;
    char s[1000010];
    vector<ll>e[1000010];
    void add(ll u,ll v)
    {e[u].push_back(v);
    }
    ll C(ll n,ll m,ll p)
    {return (n>=m&&n>=0&&m>=0)?(jc[n]*jc_inv[n-m])%p*jc_inv[m]%p:0;
    }
    void dfs(ll x,ll fa,ll k)
    {siz[x]=1;dep[x]=dep[fa]+1;for(ll i=0;i<e[x].size();i++){dfs(e[x][i],x,k);siz[x]+=siz[e[x][i]];}ans=(ans+(2*dep[x]%p-1+p)%p*C(siz[x],k,p)%p)%p;
    }
    int main()
    {
    #define Isaac
    #ifdef Isaacfreopen("string.in","r",stdin);freopen("string.out","w",stdout);
    #endifll n,k,i,j;scanf("%lld%s",&k,s+1);n=strlen(s+1);for(i=2,nxt[1]=j=0;i<=n;i++){while(j>=1&&s[i]!=s[j+1]){j=nxt[j];}j+=(s[i]==s[j+1]);nxt[i]=j;}inv[1]=jc[0]=jc_inv[0]=jc[1]=jc_inv[1]=1;for(i=2;i<=n+1;i++){inv[i]=(p-p/i)*inv[p%i]%p;jc[i]=jc[i-1]*i%p;jc_inv[i]=jc_inv[i-1]*inv[i]%p;}for(i=1;i<=n;i++){add(nxt[i],i);}dfs(0,n+1,k);printf("%lld\n",ans);return 0;
    }
    

\(T2\) B. 取石子 \(20pts\)

  • 部分分

    • \(20pts\) :暴力建博弈树。
    点击查看代码
    int a[50010];
    vector<pair<int,int> >ans;
    bool dfs(int last,int n)
    {for(int i=1;i<=n;i++){for(int j=1;j<=min(a[i],last);j++){a[i]-=j;bool tmp=dfs(j,n);	a[i]+=j;if(tmp==false){return true;}}}return false;
    }
    bool work(int k,int n)
    {for(int i=1;i<=n;i++){for(int j=1;j<=min(a[i],k);j++){a[i]-=j;bool tmp=dfs(j,n);	a[i]+=j;if(tmp==false){ans.push_back(make_pair(i,j));}}}return ans.size();
    }
    int main()
    {
    #define Isaac
    #ifdef Isaacfreopen("nim.in","r",stdin);freopen("nim.out","w",stdout);
    #endifint n,k,i;scanf("%d%d",&n,&k);for(i=1;i<=n;i++){scanf("%d",&a[i]);}sort(a+1,a+1+n);if(work(k,n)==true){printf("1\n");sort(ans.begin(),ans.end());for(i=0;i<ans.size();i++){printf("%d %d\n",ans[i].first,ans[i].second);}}else{printf("0\n");}return 0;
    }
    
  • 正解

    • 正在改,你先别着急。

\(T3\) C. 均衡区间 \(25pts\)

  • 部分分

    • 测试点 \(1 \sim 2,4 \sim 6\):模拟。

      点击查看代码
      int a[1000010],ans[1000010];
      void work(int n)
      {memset(ans,0,sizeof(ans));for(int i=1;i<=n;i++){int minn=0x7f7f7f7f,maxx=0;for(int j=i;j<=n;j++){minn=min(minn,a[j]);maxx=max(maxx,a[j]);if(minn!=min(a[i],a[j])&&maxx!=max(a[i],a[j])){ans[i]++;}}}
      }
      int main()
      {
      #define Isaac
      #ifdef Isaacfreopen("interval.in","r",stdin);freopen("interval.out","w",stdout);
      #endifint n,id,i;scanf("%d%d",&n,&id);for(i=1;i<=n;i++){scanf("%d",&a[i]);}work(n);for(i=1;i<=n;i++){printf("%d ",ans[i]);}printf("\n");reverse(a+1,a+1+n);work(n);reverse(ans+1,ans+1+n);for(i=1;i<=n;i++){printf("%d ",ans[i]);}printf("\n");return 0;
      }
      
    • 测试点 \(3\) : 不横跨 \(i\) 时端点处一定同时为最值,横跨 \(i\) 时端点处一定有至少一个取到最小值,故输出 \(0\)

  • 正解

    • 以求解左端点为例。
    • \(xl_{i},nl_{i},xr_{i},nr_{i}\) 分别表示 \(i\) 左侧第一个比它大的数,左侧第一个比它小的数,右侧第一个比它大的数,右侧第一个比它小的数,单调栈预处理即可。
    • \(i\) 不为最值时,右端点 \(j\) 需满足 \((i,j]\) 中出现了 \(>a_{i}\)\(<a_{i}\) 的数,即 \(j \ge \max(xr_{i},nr_{i})\) ;但又需要保证 \(a_{j}\) 不为最值,类似地有 \(i \le \min(xl_{j},nl_{j})\)
    • 因空间略卡,使用扫描线加树状数组维护二维数点即可。
    点击查看代码
    struct BIT
    {int c[1000010];int lowbit(int x){return (x&(-x));}void clear(){memset(c,0,sizeof(c));}void add(int n,int x,int val){for(int i=x;i<=n;i+=lowbit(i)){c[i]+=val;}}int getsum(int x){int ans=0;for(int i=x;i>=1;i-=lowbit(i)){ans+=c[i];}return ans;}
    }T;
    struct node
    {int pos,x,val,id;
    }q[2000010];
    int a[1000010],L[1000010],R[1000010],ans[1000010],cnt;
    stack<int>s1,s2;
    bool cmp(node a,node b)
    {return a.pos<b.pos;
    }
    void add(int pos,int x,int val,int id)
    {cnt++;q[cnt].pos=pos;q[cnt].x=x;q[cnt].val=val;q[cnt].id=id;
    }
    void work(int n)
    {cnt=0;memset(q,0,sizeof(q));memset(ans,0,sizeof(ans));while(s1.empty()==0){s1.pop();}while(s2.empty()==0){s2.pop();}for(int i=1;i<=n;i++){while(s1.empty()==0&&a[s1.top()]<=a[i]){s1.pop();}while(s2.empty()==0&&a[s2.top()]>=a[i]){s2.pop();}L[i]=min((s1.empty()==0)?s1.top():0,(s2.empty()==0)?s2.top():0);s1.push(i);s2.push(i);}while(s1.empty()==0){s1.pop();}while(s2.empty()==0){s2.pop();}for(int i=n;i>=1;i--){while(s1.empty()==0&&a[s1.top()]<=a[i]){s1.pop();}while(s2.empty()==0&&a[s2.top()]>=a[i]){s2.pop();}R[i]=max((s1.empty()==0)?s1.top():n+1,(s2.empty()==0)?s2.top():n+1);s1.push(i);s2.push(i);if(R[i]<=n){add(R[i]-1,i,-1,i);add(n,i,1,i);}}sort(q+1,q+1+cnt,cmp);for(int i=1,j=1;i<=cnt;i++){for(;j<=q[i].pos;j++){if(L[j]>=1){T.add(n,L[j],1);}}ans[q[i].id]+=q[i].val*(T.getsum(n)-T.getsum(q[i].x-1));}
    }
    int main()
    {
    #define Isaac
    #ifdef Isaacfreopen("interval.in","r",stdin);freopen("interval.out","w",stdout);
    #endifint n,id,i;scanf("%d%d",&n,&id);for(i=1;i<=n;i++){scanf("%d",&a[i]);}work(n);for(i=1;i<=n;i++){printf("%d ",ans[i]);}printf("\n");reverse(a+1,a+1+n);work(n);reverse(ans+1,ans+1+n);for(i=1;i<=n;i++){printf("%d ",ans[i]);}printf("\n");return 0;
    }
    

\(T4\) D. 禁止套娃 \(10pts\)

  • 部分分

    • \(10pts\) :爆搜求本质不同子序列个数。
    点击查看代码
    const ll p=1000000007;
    int a[5010],ans=0;
    vector<int>state,tmp;
    map<vector<int>,bool>s1,s2;
    void dfs2(int pos)
    {if(pos==state.size()){if(s2.find(tmp)==s2.end()){s2[tmp]=1;ans=(ans+1)%p;}}else{dfs2(pos+1);tmp.push_back(state[pos]);dfs2(pos+1);tmp.pop_back();}
    }
    void dfs(int pos,int n)
    {if(pos==n+1){if(s1.find(state)==s1.end()){s2.clear();dfs2(0);s1[state]=1;}}else{dfs(pos+1,n);state.push_back(a[pos]);dfs(pos+1,n);state.pop_back();}
    }
    int main()
    {
    #define Isaac
    #ifdef Isaacfreopen("nest.in","r",stdin);freopen("nest.out","w",stdout);
    #endifint n,i;cin>>n;for(i=1;i<=n;i++)	{cin>>a[i];}dfs(1,n);cout<<ans<<endl;return 0;
    }
    
  • 正解

总结

  • \(T3\) 性质场上没推出来。

后记

  • 下发题面和题解的 \(PDF\) 题面中的 \(\LaTeX\) 炸了。
  • \(T1\) 题面 \(i,j\) 写反了。
  • \(T3\) 题解 \(i \le L_{j}\) 打成了 \(i \ge L_{j}\)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/836956.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在微信中使用AI聊天机器人

微信是中国最流行的社交通讯软件,具有庞大的用户基础。ChatGPT是由 OpenAI 开发的、当前最先进的AI聊天机器人,ChatGPT 尤其是在理解和生成自然对话方面表现出色,能够进行流畅且连贯的交流。对中国人而言,将 ChatGPT 集成到微信中,可以在一个熟悉的环境中体验到最新的人工…

protodep踩坑

在使用微服务框架go-zero时,服务拆分比较多,每更新一个服务的proto文件,都要手动复制pb文件到调用的服务里面,新系统开发的时候决定用protodep解决这个问题。 protodep 是一款专为Protocol Buffers接口描述语言文件设计的依赖管理工具。它解决了在使用gRPC时,如何有效控制…

虚幻4 蓝图无法保存 解决方法

蓝图类只能存放在 Blueprints文件夹内,创建在其他文件夹的蓝图类无法保存。 可以看到无法将蓝图拖动到其他文件夹内。这是一个存放在其他文件夹下的蓝图类:当尝试按Ctrl+shift+A保存时,将出现如下错误:解决方法是,将当前蓝图删除(注意,如果该蓝图从某个C++类继承而来,那…

理解进程调度时机跟踪分析进程调度与进程切换的过程

张晓攀+原创作品转载请注明出处+《Linux内核分析》MOOC课程https://mooc.study.163.com/course/1000029000 实验八——理解进程调度时机跟踪分析进程调度与进程切换的过程 一、理解Linux系统中进程调度的时机 在 Linux 内核中,schedule() 函数是核心的进程调度机制。它的主要作…

李继刚Lisp提示词灵感之源:压缩推动进步

探秘李继刚Lisp提示词压缩表达的灵感来源:德国计算机科学家尤尔根施密德胡伯提出,智能系统通过学习新技能来更高效地预测或压缩信息,这种内在动力推动了好奇心和创造力的发展,适用于从婴儿探索世界到科学家发现新规律的各种场景。前面在文章《 访谈李继刚:从哲学层面与大模…

java:找不到符号 符号:变量:log

原文链接:https://blog.csdn.net/zhanghaoninhao/article/details/129180810问题:java:找不到符号 符号:变量:log环境:springboot idea解决方法:在idea中,点击file-Settings,打开配置页面,如图红框位置,输入: -Djps.track.ap.dependencies=false

【SolidWorks 2024下载与安装教程】

‌SolidWorks 2024是一款由达索系统(Dassault Systemes)开发的三维CAD软件,广泛应用于机械设计、产品开发、工程设计、制造等领域。‌ 该软件以其强大的功能和易学易用的特点,深受工程师和设计师的喜爱。SolidWorks 2024在2024版本中引入了一系列新功能和改进,旨在提高设计效…

20222315 2024-2025-1 《网络与系统攻防技术》实验五实验报告

1、实验内容 1)从www.besti.edu.cn、baidu.com、sina.com.cn中选择一个DNS域名进行查询,获取如下信息: DNS注册人及联系方式 该域名对应IP地址 IP地址注册人及联系方式 IP地址所在国家、城市和具体地理位置 PS:使用whois、dig、nslookup、traceroute、以及各类在线和离线工…

编程命名规范(网文)

一个好的变量或函数命名,应该能起到自解释的作用,甚至能减少我们代码的注释。 naming-cheatsheet是一个命名备忘录,记录一些常见的规范约定,并提供简单的例子说明。如果能够严格遵守这些规范,相信我们的代码可读性会大大提升,下面就来介绍 naming-cheatsheet 提供的一些建…

MyBatis 学习笔记

MyBatis 执行器 JDBC 的执行过程分为四步:获取数据库连接(Connection) 预编译 SQL(PrepareStatement) 设置参数 执行 SQL(ResultSet)MyBatis 提供了执行器 Executor 将这一过程进行封装,对外提供 SqlSession 让用户通过调用其 API 直接操作数据库,因为 SqlSession 持有…

机器学习:线性回归

章节安排背景介绍 均方根误差MSE 最小二乘法 梯度下降 编程实现背景生活中大多数系统的输入输出关系为线性函数,或者在一定范围内可以近似为线性函数。在一些情形下,直接推断输入与输出的关系是较为困难的。因此,我们会从大量的采样数据中推导系统的输入输出关系。典型的单输…