[NOIP]模拟17 题解
A.入阵曲
部分分很肥,正解写得常数稍大就会和暴力一个分,考试的时候写什么自己考虑。(滑稽
部分分的循环边界手抖写错了-25 (原本暴力分中的10分都没了啊啊啊)
没写挂的话应该有75,其实就是二维前缀和+暴力枚举点对统计+$a[i][j]$都相等时只枚举子矩形大小再乘上这种大小出现的次数。
正解:$(sum[r]-sum[l-1])\% K=0 \rightarrow sum[r]\% K=sum[l-1]\% K$
枚举行数$i,j$和列数$k$,维护i行和j行之间、k列左侧在%K意义下同余矩阵的个数,用桶来实现。
#include<cstdio> #include<iostream> #include<cstring> using namespace std; typedef long long ll; const int N=650; int n,m; ll K,ans; int a[N][N]; ll sum[N][N],sum1[N],cnt[1000005]; 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-'0',ch=getchar();return x*f; }int main() {n=read();m=read();K=1LL*read();for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i][j]=read();for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+1LL*a[i][j];for(int i=0;i<n;i++)for(int j=i+1;j<=n;j++){cnt[0]=1;for(int k=1;k<=m;k++){sum1[k]=(sum[j][k]-sum[i][k]+K)%K;ans+=cnt[sum1[k]];cnt[sum1[k]]++;}for(int k=1;k<=m;k++)cnt[sum1[k]]=0;}cout<<ans<<endl;return 0; }
View Code
B.将军令
我考场都能想到的sb贪心。每次取出深度最大且未被覆盖的点,在它的K级祖先上驻扎即可。前者用堆维护,后者直接暴力修改覆盖状态,注意向上修改时不要只遍历和它在一条链上的。
正确性?读者自证不难。(逃
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #define pa pair<int,int> #define re register using namespace std; 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-'0',ch=getchar();return x*f; } const int N=100005; int n,K,t; int to[N<<1],nxt[N<<1],head[N],tot; inline void add(int x,int y) {to[++tot]=y;nxt[tot]=head[x];head[x]=tot; } int dep[N],fa[N]; priority_queue<pa> q; void dfs1(int x,int deep) {dep[x]=deep;for(re int i=head[x];i;i=nxt[i]){int y=to[i];if(!dep[y])dfs1(y,deep+1),fa[y]=x;}return ; } int cover[N],anc,ans; void getan(int x,int rest) {if(!rest||x==1){anc=x;return ;}getan(fa[x],rest-1);return ; } void dfs2(int x,int rest,int f) {cover[x]=1;if(!rest)return ;for(re int i=head[x];i;i=nxt[i]){int y=to[i];if(y==f)continue;dfs2(y,rest-1,x);}return ; }int main() {n=read();K=read();t=read();for(re int i=1;i<n;i++){int x=read(),y=read();add(x,y);add(y,x);}dfs1(1,1);for(re int i=1;i<=n;i++)q.push(make_pair(dep[i],i));while(!q.empty()){int x=q.top().second;q.pop();if(cover[x])continue;getan(x,K);//cout<<anc<<endl;dfs2(anc,K,-1);ans++;}cout<<ans<<endl;return 0; }
View Code
C.星空
区间状态反转可以看作区间异或1,但区间操作不好处理,考虑通过差分转化为单点操作。即把对原数组上$[L,R]$区间的操作转化为差分数组上$L-1$和$R$两个点的操作。这里用到了异或差分:$dif[i]=a[i]\ xor\ a[i+1]$
所以问题变成了:有一个01串,每次对其中两个点$xor\ 1$,需要多少次把这个串的每一位都变成0。(差分数组全0对应原数组全1)
可以发现,消去两个1的费用与他们之间的距离有关。bfs预处理出来后,问题再次得到转化:每次取出一对物品,每对物品取出都有一定代价,如何取出使得代价最小。由于不亮的灯泡很少,这个问题完全可以状压解决。
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #include<vector> using namespace std; 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-'0',ch=getchar();return x*f; } const int N=40005; int n,m,K; int a[N],op[N],dif[N]; int pos[N],sz; int vis[N],dis[20][20],d[N]; int find0[N<<1],dp[N<<1]; void bfs(int node) {memset(d,0,sizeof(d));memset(vis,0,sizeof(vis));queue<int> q;q.push(node);vis[node]=1;d[node]=0;while(!q.empty()){int x=q.front();q.pop();for(int i=1;i<=m;i++){int s1=x+op[i],s2=x-op[i];if(s1<=n&&!vis[s1]){q.push(s1);d[s1]=d[x]+1;vis[s1]=1;}if(s2>=0&&!vis[s2]){q.push(s2);d[s2]=d[x]+1;vis[s2]=1;}}} }int main() {n=read();K=read();m=read();for(int i=1;i<=K;i++)a[read()]=1;for(int i=1;i<=m;i++)op[i]=read();for(int i=0;i<=n;i++){dif[i]=a[i]^a[i+1];if(dif[i])pos[++sz]=i;}for(int i=1;i<=sz;i++){bfs(pos[i]);for(int j=1;j<=sz;j++)dis[i][j]=d[pos[j]];}for(int s=0;s<(1<<sz);s++){find0[s]=sz-1;for(int i=0;i<sz;i++)if(((s>>i)&1)==0){find0[s]=i;break;}}memset(dp,0x3f,sizeof(dp));dp[0]=0;for(int s=0;s<(1<<sz);s++)for(int i=find0[s]+1;i<sz;i++){if(((s>>i)&1)==0&&dis[find0[s]+1][i+1]){int now=(s|(1<<find0[s])|(1<<i));dp[now]=min(dp[now],dp[s]+dis[find0[s]+1][i+1]);//cout<<dp[now]<<endl; }}cout<<dp[(1<<sz)-1]<<endl;return 0; }
View Code
转载于:https://www.cnblogs.com/Rorschach-XR/p/11342841.html
[NOIP]模拟17 题解相关推荐
- NOIP模拟17.10.12
T1 临江仙 旧梦 题目背景 闻道故园花陌,今年奼紫嫣红.扬帆直渡水千重.东君何解意,送我一江风. 还是昔时庭院,终得醉卧花丛.残更惊醒月明中.流光如旧岁,多少梦成空. 题目描述 #define go ...
- [NOIP模拟16]题解
A.Blue 出题人大概已经去为国家处理积压子弹了? 贪心,让每一只青蛙(我怂行吧)都尽量往远跳,能到达的最远的被踩了就跳次远的,以此类推.可以维护一个单调队列,表示每只青蛙的位置(开始都是0).然后 ...
- 第一届『Citric杯』NOIP提高组模拟赛 题解
[官方题解]第一届『Citric杯』NOIP提高组模拟赛 题解 第一题 柠檬超市 这题是本次模拟赛的送分题.做法显然. 但是注意此题有一个陷阱: 注意W和C的规模都是10^9,所以如果直接用doubl ...
- NOIP 模拟赛 长寿花 题解
NOIP 模拟赛 长寿花 题解 要放 \(n\) 层物品,第 \(i\) 层有 \(a_i\) 个位置放物品,物品有 \(m\) 中颜色,有约束条件: 同一层两个相邻物品颜色不能相同. 相邻两层颜色集 ...
- Noip 模拟练习5
Noip 模拟练习5 满分300,本人240.修正后300. 难度中等. 太空密码 Description 人类一直致力于探索地外文明,为此科学家们建造了一个巨大的射电望远镜 用于接收宇宙射线.一天从 ...
- NOIP模拟赛 四校联考 递推 + 分类讨论 + 树上期望
NOIP 模拟题 题目名称兔子被子蚊子 源程序文件名rabbit.cpp quilt.cpp mosquito.cpp 输入文件名rabbit.in quilt.in mosquito.in 输出文件 ...
- 辣鸡(ljh) NOIP模拟赛 模拟 平面几何 数论 化学相关(雾)
[题目描述] 辣鸡ljhNOI之后就退役了,然后就滚去学文化课了. 然而在上化学课的时候,数学和化学都不好的ljh却被一道简单题难住了,受到了大佬的嘲笑. 题目描述是这样的:在一个二维平面上有一层水分 ...
- NOI.AC NOIP模拟赛 第六场 游记
NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...
- [CQOI2012]模拟工厂 题解(搜索+贪心)
[CQOI2012]模拟工厂 题解(搜索+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327574 链接题目地址:洛谷P3161 BZOJ P26 ...
最新文章
- [笔记]用VS2010编译运行项目时报“LINK : fatal error LNK1104:...
- zabbix数据库表结构简单解析
- jqgrid编辑php,php – 实现jqgrid单元格编辑datepicker
- 使用dime传输大附件的设置(WSE Soap toolkit)
- C++视频教程资源链接合集
- Matlab注释多行和取消多行注释的快捷键
- 索尼电视总出现Android,索尼电视紧急撤回安卓8.0固件包:N多用户无法连接Wi-Fi...
- 【Linux】循序渐进学运维-学习方法篇
- CAD-Arcgis 坐标校正
- python电子病历,如何在电子病历上安装软件包
- 北京软件开发公司排名-最大的软件开发公司有哪些呢
- 心灵捕手——走进内心世界
- 「PKUSC2018」星际穿越
- python读取配置文件 分段_python分割文件的常用方法
- 如何透过上层div点击下层的元素
- js求三个数的最大值和最小值
- 怎样把电脑D盘合并到c盘?相邻的分区怎么合并到C盘
- 关于数学中的正弦定理和余弦定理的相关信息的概述
- 缺货笼罩供应链:智能手机“涨”声一片
- ViT 家族的大杂烩(An Image is worth 16×16 Words)
热门文章
- Effective C++ 条款13 以对象管理资源
- uniapp、uniCloud实现微信公众号自动查询淘宝京东优惠券制作过程
- Vue——v-show的使用——2020.11.18
- 图像处理半色调技术(matlab/C++)
- 达芬奇17新功能及安装教程
- 全球及中国汽车自动驾驶用胶粘剂行业市场发展态势与需求前景预测报告2022-2028年
- wps如何在html中在线浏览器,wps如何设置表格内链接用电脑默认浏览器打开
- mysql 5.6 64 位安装 缺少libai.so_CentOS6.7安装部署LNMP(nginx1.8.0+php5.6.10+mysql5.6.12) 法外狂徒...
- 链接的接口——符号(一)链接错误:symbol lookup error: xxx, undefined symbol: xxx
- 史上最全数据库笔记(上)