NOIP-2022 题解

T1

一眼是计数类的题目,那就要思考怎么计数了
这道题目还是很简单的
类似于动态规划,只要找到转移的方法就行了,从哪里可以做出来
首先 , 先考虑 C 因为 F 是 C 下边随便加一个点 , 所以只要求出 C 就求出了 F 。 首先, 先考虑 C 因为 F 是 C 下边随便加一个点, 所以只要求出 C 就求出了 F 。 首先,先考虑C因为FC下边随便加一个点,所以只要求出C就求出了F
下边来考虑如何求 C 。 下边来考虑如何求 C 。 下边来考虑如何求C
注意到 , 他并没有要求上下行一样 , 唯一的要求是 C 的两个横要隔一行 , 这就是问题的突破点 , 这题很明显的计数 . 注意到, 他并没有要求上下行一样, 唯一的要求是 C 的两个横要隔一行, 这就是问题的突破点, 这题很明显的计数. 注意到,他并没有要求上下行一样,唯一的要求是C的两个横要隔一行,这就是问题的突破点,这题很明显的计数.
计数用到什么 ? 乘法原理 , 加法原理。 计数用到什么? 乘法原理, 加法原理。 计数用到什么?乘法原理,加法原理。
假设上边的有 a 个合法的横 , 那考虑这一行每一个合法的横(这里说的不同是长度不同)给答案的贡献是什么 ? 假设上边的有 a 个合法的横, 那考虑这一行每一个合法的横(这里说的不同是长度不同)给答案的贡献是什么? 假设上边的有a个合法的横,那考虑这一行每一个合法的横(这里说的不同是长度不同)给答案的贡献是什么?
是不是每一个贡献 a , 那这一行有 b 个不同的合法的横 , 那么答案就增加了 a × b , 是不是每一个贡献 a , 那这一行有 b 个不同的合法的横, 那么答案就增加了 a \times b , 是不是每一个贡献a,那这一行有b个不同的合法的横,那么答案就增加了a×b,
那每一行都这么处理 , 然后处理完一样就加上上一行的合法的方案数(因为他要求两个横之间至少隔一行)。 那每一行都这么处理, 然后处理完一样就加上上一行的合法的方案数(因为他要求两个横之间至少隔一行)。 那每一行都这么处理,然后处理完一样就加上上一行的合法的方案数(因为他要求两个横之间至少隔一行)。
当遇到土坑的时候就把记录数组清零即可 . 当遇到土坑的时候就把记录数组清零即可. 当遇到土坑的时候就把记录数组清零即可.
C 解决了 , 那就是 F 了、想要求出 F , 只要求出这一列上有多少合法的 C 就行了(因为 F 是由 C 下边加上一个坚构成的) , C 解决了, 那就是 F 了、想要求出 F , 只要求出这一列上有多少合法的 C 就行了(因为 F 是由 C 下边加上一个坚构成的), C解决了,那就是F了、想要求出F,只要求出这一列上有多少合法的C就行了(因为F是由C下边加上一个坚构成的),
所所以我们只要复制过来记录 C 的公式然后把他存在另一个数组里到时候每找到一个能种花的地方 F 的答案加上这个数组就好了。 所所以我们只要复制过来记录 C 的公式然后把他存在另一个数组里到时候每找到一个能种花的地方 F 的答案加上这个数组就好了。 所所以我们只要复制过来记录C的公式然后把他存在另一个数组里到时候每找到一个能种花的地方F的答案加上这个数组就好了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MOD=998244353;
int read(){int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;
}
const int N=1010;
int ans1,ans2,c,F;
int n,m,id,T;
int f[N][N];
int js,j2;
char mp[N][N];
signed main() {T=read(),id=read();while(T--) {memset(f,0,sizeof f);n=read(),m=read();c=read(),F=read();for(int i=1; i<=n; i++) {for(int j=1; j<=m; j++) {cin>>mp[i][j];	}}for(int i=1; i<=n; i++){for(int j=m-1; j>=1; j--) {if(mp[i][j]=='1') f[i][j]=-1;else if(mp[i][j+1]=='0') f[i][j]=f[i][j+1]+1;}}for(int j=1; j<m; j++) {js=j2=0;for(int i=1; i<=n; i++) {if(f[i][j]==-1) {j2=js=0;continue ;}ans1=ans1%MOD+(1ll*f[i][j]*(js%MOD))%MOD;ans2=(ans2%MOD+j2%MOD)%MOD;j2=(j2+(1ll*f[i][j]*(js%MOD))%MOD)%MOD;js=js+max((int)0,f[i-1][j]);}}cout<<(c*ans1)%MOD<<' '<<(F*ans2)%MOD<<endl;ans1=ans2=0;}return 0;
}

T2

这道题还是有一点难度的
优先跳过
回头再看这个题,感觉很好理解,一开始没有关注k的范围,现在一看,发现k只有两种方案,所以只需要对k进行讨论就行了
k = 2 ( n − 1 ) k=2(n-1) k=2(n1) 时,这个时候就可以在每个栈中放入两个元素,然后留出来一个特殊栈,特殊栈就是要消元素用的。

这样对于某个栈, 来一个属于该栈的卡牌时, 若和底部卡牌相同就利用特殊栈进行 2 操作, 否则就直接放上去。这样可以保证每时每刻, 前 n-1 个栈的卡牌个数不超过 2 。

k = 2 n − 1 k=2 n-1 k=2n1 时, 此时会出现一种情况: n − 1 n-1 n1 个栈都包含 2 2 2 个卡牌了, 此时又来最后一种卡牌。设该卡牌为 w w w , 找到 n − 1 n-1 n1 个放满的栈中底部卡牌之后最先出现的栈 x x x, x x x 栈底设为 u u u , 栈顶设为 v v v , 分下面三种情况讨论:

  • w w w 的下一次出现时间早于 u u u , 那么可以 w w w 直接放到特殊栈(因为特殊栈的作用是消除底部, 在 u u u 下次出现之前都不会用到特殊栈)
  • u u u 下次出现时间早于 v v v , 那么可以把 w w w 放到 x x x 顶部(虽然此时栈内会有 3 3 3 个卡牌导致中间的 v v v 无法消除,但是 u u u 会早于 v v v 离开)
  • 剩下的情况意味着下次出现的时间是 v < u < w v<u<w v<u<w ,那么可以把 w w w 放到特殊栈,然后规定接下来的特殊栈改为 x x x (很明显在 x x x 清空之前,都不会存在 2 2 2 操作,所以没影响)

优化成 O ( m ) O(m) O(m) 要注意几个点:

  • 需要一个数组维护每个卡牌当前所在栈的编号
  • 需要一个队列来分配每个新来的卡牌属于哪个普通栈的,初始每个普通栈能提供两个空位,卡牌出栈会归还空位
  • 查找下一个最先出现底部元素的栈,可以暴力往后找,因为下一次再出现放满栈的局面一定在底部元素出栈后(若是第一种情况 w w w 先出,就循环到下个 w w w 结束)。这样所有暴力找的部分不会有交叉, 总循环次数不超过 m m m
#include<bits/stdc++.h>
using namespace std;
int rd(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;
}
const int N=2e6+10;
int T,n,m,k,a[N],cnt,spe,belong[N];
struct node{int op,x,y;}ans[N<<2];
vector<deque<int> > s(310);
queue<int> q;
void opera1(int x,int t){ans[++cnt]={1,x};if(s[x].size()>0&&s[x].back()==t){s[x].pop_back();if(x!=spe&&s[x].size()<2) q.push(x);belong[t]=0;}else{s[x].push_back(t);belong[t]=x;}
}
void opera2(int x,int y){ans[++cnt]={2,x,y};belong[s[x].front()]=0;s[x].pop_front(),s[y].pop_front();if(s[x].size()<2) q.push(x);
}
void init(){while(!q.empty()) q.pop();cnt=0;s.clear();s.resize(310);for(int i=0;i<=k;i++) belong[i]=0;
}
int main(){T=rd;while(T--){init();n=rd,m=rd,k=rd;for(int i=1;i<=m;i++) a[i]=rd;for(int i=1;i<=n-1;i++) q.push(i),q.push(i);spe=n;for(int i=1;i<=m;i++){int x=belong[a[i]];if(x){if(s[x].size()==1) opera1(x,a[i]);else if(s[x].back()==a[i]) opera1(x,a[i]);else opera1(spe,a[i]),opera2(x,spe);}else if(q.size()>0){x=q.front();q.pop();opera1(x,a[i]);}else{for(int j=i+1;;j++){if(a[j]==a[i]) break;if(s[belong[a[j]]].front()==a[j]){x=belong[a[j]];break;}}if(!x) opera1(spe,a[i]);else{int u=s[x].front(),v=s[x].back();for(int j=i+1;;j++){if(a[j]==u){opera1(x,a[i]);break;}else if(a[j]==v){opera1(spe,a[i]),q.push(spe),spe=x;break;}}} }}printf("%d\n",cnt);for(int i=1;i<=cnt;i++){if(ans[i].op==1) printf("%d %d\n",ans[i].op,ans[i].x);else printf("%d %d %d\n",ans[i].op,ans[i].x,ans[i].y);}}return 0;
}

T3

这道题之前做过,所以回忆出来还是比较简单的
就是在本地不知道为什们过不了大样例
A 国可以随意地看守或不看守不是割边的边。因此想到 边双缩点 后树形 DP
V u V_{u} Vu 表示双连通分量 u u u 中的点数, E u E_{u} Eu 表示双连通分量 u u u 中的边数, 若有 n n n 个双连通分量, 则问题转化为:

给定一棵无根树, 每个结点有 2 E u 2^{E_{u}} 2Eu 种不建造军营的方案和 ( 2 V u + E u − 2 E u ) \left(2^{V_{u}+E_{u}}-2^{E_{u}}\right) (2Vu+Eu2Eu) 种建造军营的方案。求共有多少种建造军营的方案 (不能不建)。

这里假定 1 1 1 号结点为树根。
f ( u , 0 / 1 ) f(u, 0 / 1) f(u,0/1) 表示以 u 为根的子树中没有/有军营的方案数。
发现每种状态所涵盖的情况过多, 根本不好转移。
这时, 有两种思路:

  • 增加状态数量。
  • 对状态增添限制。

我选择的是后者。
f ( u , 0 / 1 ) f(u, 0 / 1) f(u,0/1) 表示以 u u u 为根的子树中没有/有军营的方案数, 若有军营, 则所有的军营必须通过已经派兵看守的边与 u u u 连通。

在想转移之前, 为了防止做无用功, 最好先想想该如何统计答案。
对于每个结点 u u u , 我们强制 u u u 子树外的所有点都不建军营, 同时强制不选 f a u → u f a_{u} \rightarrow u fauu 的边, 再累加方案数, 即可保证不重不漏

#include<bits/stdc++.h>
using namespace std;#define int long longint read(){int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;
}
const int N=1e6+10;
int head[N],tot=1;
struct node{int to,nxt;
}e[N*2];
void add(int a,int b){tot++;e[tot].to=b;e[tot].nxt=head[a];head[a]=tot;
}
int n,m;
bool ban[N*4];
int vis[N],cnt[N],f[N][10];
void dfs(int x,int fa){
//	puts("dfs1");vis[x]=1;for(int i=head[x];i;i=e[i].nxt){int y=e[i].to;if(y==fa||ban[i]) continue;if(vis[y]) {ban[i]=ban[i^1]=1;cnt[x]+=1,cnt[y]-=1;continue;}dfs(y,x);}
}
void dfs2(int x,int fa){
//	puts("dfs2");for(int i=head[x];i;i=e[i].nxt){int y=e[i].to;if(y==fa||ban[i]) continue;dfs2(y,x),cnt[x]+=cnt[y];}
}
const int MOD=1e9+7;
void work(int x,int fa){
//	puts("work");f[x][0]=f[x][1]=1;f[x][2]=0;for(int i=head[x];i;i=e[i].nxt){int y=e[i].to;if(y==fa||ban[i]) continue;work(y,x);int t1=0,t2=0,t0=0;if(cnt[y]){t0=2*f[x][0]*f[y][0]%MOD;t1=(2*f[x][0]*f[y][1]%MOD+2*f[x][1]*f[y][0]%MOD+2*f[x][1]*f[y][1]%MOD)%MOD;t2=(2*f[x][0]*f[y][2]%MOD+2*f[x][2]*f[y][0]%MOD)%MOD;}else{t0=2*f[x][0]*f[y][0]%MOD;t1=(f[x][0]*f[y][1]%MOD+2*f[x][1]*f[y][0]%MOD+f[x][1]*f[y][1]%MOD)%MOD;t2=(2*f[x][0]*f[y][2]%MOD+2*f[x][2]*f[y][0]%MOD+f[x][0]*f[y][1]%MOD)%MOD;}f[x][0]=t0,f[x][1]=t1,f[x][2]=t2;}
}
signed main(){
//	freopen("barrack4.in","r",stdin);
//	freopen("1.out","w",stdout);n=read(),m=read();for(int i=1;i<=m;i++){int a=read(),b=read();add(a,b),add(b,a);}
//	puts("popopopopopopopopop");dfs(1,0),dfs2(1,0);work(1,0);
//	cout<<"______________________________";int ans=(f[1][1]+f[1][2])%MOD;for(int i=1;i<=m-n+1;i++){ans=(ans<<1)%MOD;}printf("%lld",ans);return 0;
} 

T4

看同学们写了线段树,但是写挂了
好像要学新知识了
这道题能力有限,只能写部分分了,会了矩阵再说
然后这就是暴力:
考虑离线做, 对所有询问按照 r r r 从小到大一个个来。假设当前考虑到 r r r , 记 x i = max ⁡ j = i r a j , y i = max ⁡ j = i r b j , f i = ∑ j = i r x j y j x_{i}=\max _{j=i}^{r} a_{j}, y_{i}= \max _{j=i}^{r} b_{j}, f_{i}=\sum_{j=i}^{r} x_{j} y_{j} xi=maxj=iraj,yi=maxj=irbj,fi=j=irxjyj , 那么对于询问 ( l , r ) (l, r) (l,r) , 答案就是 ∑ i = l r f i \sum_{i=l}^{r} f_{i} i=lrfi 。这样时间复杂度变为 O ( n 2 + n q ) O\left(n^{2}+n q\right) O(n2+nq) , 可以拿到 20 分的高分, 参考代码如下:

#include<bits/stdc++.h>
using namespace std;
#define ULL unsigned long long 
struct Node {int l, id;
};
const int N=1e6+10;
vector<Node> d[N];
ULL a[N], b[N];
ULL f[N], x[N], y[N];
ULL ans[N];
int main() {int n, q;scanf("%*d%d", &n);for (int i = 1; i <= n; i++) {scanf("%llu", &a[i]);}for (int i = 1; i <= n; i++) {scanf("%llu", &b[i]);}scanf("%d", &q);for (int i = 1; i <= q; i++) {int l, r;scanf("%d%d", &l, &r);d[r].push_back({l, i});}for (int r = 1; r <= n; r++) {for (int i = 1; i <= r; i++) {x[i] = max(x[i], a[r]);y[i] = max(y[i], b[r]);f[i] += x[i] * y[i];}for (auto [l, id] : d[r]) {for (int i = l; i <= r; i++)ans[id] += f[i];}}for (int i = 1; i <= q; i++) printf("%llu\n", ans[i]);return 0;
}

正解还不会,头考NOIP如果补题的话再改

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

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

相关文章

SpringCloud接入nacos配置中心

这里写自定义目录标题 版本选择项目搭建pom.xml本地的 application.ymlchenfu-miniapp-dev.yml 中的配置项接收配置的实体类 版本选择 spring-cloud-Alibaba版本依赖关系 本文章&#xff0c;采用的 springboot 版本是 2.6.13&#xff0c;spring-cloud-alibaba 版本是 2021.0.5…

Reduce函数

Reduce函数&#xff1a; 概念表述&#xff1a; reduce()方法是一个迭代方法对数组中的每个元素按序执行一个提供的 reducer 函数&#xff0c;每一次运行 reducer函数体会将先前元素的计算结果作为参数传入&#xff0c;最后将其结果汇总为单个返回值。用于累积运算。 执行机制&…

(二十二)、k8s 中的关键概念

文章目录 1、总体概览2、第一层&#xff1a;物理机、集群、Node、Pod 之间的关系2、第二层&#xff1a;命名空间 Namespace3、定义4、控制平面&#xff08;Control Plane&#xff09;5、特别的概念 Service6、Deployment 经过 之前几篇文章对 k8s 的实践&#xff0c;结合实践&…

QT 中彻底解决中文乱码问题的指南

在使用 QT 进行开发时&#xff0c;中文乱码问题是许多开发者常遇到的困扰。这不仅影响用户体验&#xff0c;还可能导致数据处理错误。本文将详细介绍在 QT 中彻底解决中文乱码问题的方法&#xff0c;帮助开发者创建更友好的应用程序。 一、中文乱码问题的原因 在 QT 中出现中文…

appium文本输入的多种形式

目录 一、send_keys方法 二、press_keycode方法 三、subprocess方法直接通过adb命令输入 一、send_keys方法 这个是最常用的方法&#xff0c;不过通常使用时要使用聚焦&#xff0c;也就是先点击后等待&#xff1a; element wait.until(EC.presence_of_element_located((By…

AI模型库 : 下一个大型供应链攻击目标

像 Hugging Face 这样的AI模型平台&#xff0c;很容易受到攻击者多年来通过 npm、PyPI 和其他开源存储库成功执行的同类攻击的影响 Hugging Face 等AI模型存储库为攻击者提供了与 npm 和 PyPI 等开源公共存储库相同的将恶意代码植入开发环境的机会。 在今年 4 月即将举行的 Bl…

元学习-学习笔记

学习视频&#xff1a;火炉课堂 | 元学习(meta-learning)到底是什么鬼&#xff1f;_哔哩哔哩_bilibili 一、从传统机器学习到元学习 我们传统的机器学习&#xff0c;是手工设计一个模型&#xff0c;然后将训练数据投进模型中进行训练&#xff0c;得到一个最优的模型参数&#x…

bytetrack训练日志解读和相应源码分析

文章目录 日志结构训练过程概述评估结果对应代码80个周期665次迭代概念说明损失值日志结构 2024-10-12 09:04:25 | INFO | yolox.core.trainer:179 - Training start.

文件inode

磁盘结构&#xff1a; 众所周知扇面是磁盘存储数据的地方&#xff0c;而一个磁盘有个6个磁盘面&#xff0c;而磁头指向都是相同半径的扇面&#xff0c;所以我们可以抽象出来一个三维指针&#xff1b; 这样我们就抽象出来了一个磁盘&#xff0c;而我们的每个磁盘面都有相同名字…

微信小游戏function signature mismatch,RuntimeError: function signature mismatch

我看网上很多人再搜&#xff0c;没有解决方案。开一下尘封多年的博客&#xff0c;希望能帮到有缘人。 除了其他人发的插件版本问题&#xff0c;缓存问题&#xff0c;华佗问题。 我遇到还有个情况是 Task语法和 Enable Exceptions to Full Without Stacktrace 组合的问题。 如…

MES系列- 统计过程分析(SPC)实现

MES系列文章目录 ISA-95制造业中企业和控制系统的集成的国际标准-(1) ISA-95制造业中企业和控制系统的集成的国际标准-(2) ISA-95制造业中企业和控制系统的集成的国际标准-(3) ISA-95制造业中企业和控制系统的集成的国际标准-(4) ISA-95制造业中企业和控制系统的集成的国际标准…

MMA: Multi-Modal Adapter for Vision-Language Models

两个观察 图1所示。各种基于transformer的CLIP模型中不同层的数据集级识别精度。这个实验是为了确定样本属于哪个数据集。我们用不同的种子运行了三次&#xff0c;并报告了每层识别精度的平均值和标准差。 X E m b e d XEmbed XEmbed是指变压器块之前的文本或图像嵌入层&#x…

外包干了7天,技术明显退步。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;22年通过校招进入南京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…

【银河麒麟高级服务器操作系统·实例分享】裸金属服务器开机失败分析及处理建议

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 现象描述 裸金属物理服务器开机卡在EFI stub页面…

怎么在抖音视频里标注店铺定位信息?

随着短视频平台的兴起&#xff0c;抖音作为短视频领域的佼佼者&#xff0c;凭借其庞大的用户基础和强大的营销工具&#xff0c;已然成为了众多商家推广业务、吸引顾客的重要平台。通过在抖音视频中准确标注店铺定位信息&#xff0c;不仅能增加店铺的曝光率&#xff0c;还能方便…

Spring 设计模式之策略模式

Spring 设计模式之策略模式 策略模式构成部分java举例 策略模式 策略模式&#xff1a;允许定义一系列算法&#xff0c;并将每一个算法封装起来&#xff0c;使它们可以互相替换&#xff0c;且算法的变化可以独立于使用它们的客户端。 构成部分 Context&#xff08;上下文&…

.NET 8 Web API 中的身份验证和授权

本次介绍分为3篇文章&#xff1a; 1&#xff1a;.Net 8 Web API CRUD 操作.Net 8 Web API CRUD 操作-CSDN博客 2&#xff1a;在 .Net 8 API 中实现 Entity Framework 的 Code First 方法https://blog.csdn.net/hefeng_aspnet/article/details/143229912 3&#xff1a;.NET …

详解Java之Spring MVC篇一

目录 Spring MVC 官方介绍 MVC RequestMapping 传递参数 无参数 单个参数 针对String类型 针对Integer类型 针对int类型 针对自定义类型 多个参数 参数重命名 参数强制一致 参数不强制一致 传递数组 ​编辑传递List ​编辑 传递JSON ​编辑 从路径中获取参…

Android demo文件内容记录

<style name"Theme.Demo1" parent"Theme.MaterialComponents.DayNight.DarkActionBar"><!-- Primary brand color. --><item name"colorPrimary">color/purple_500</item>//状态栏的背景色&#xff0c;优先级小于androi…

什么是微服务中的反应性扩展?

大家好&#xff0c;我是锋哥。今天分享关于【什么是微服务中的反应性扩展&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 什么是微服务中的反应性扩展&#xff1f; Reactive Extensions 也称为 Rx。这是一种设计方法&#xff0c;我们通过调用多个服务来收集结果…