[NOIP模拟23]题解
中间鸽了好几篇啊QAQ……有时间再补吧……
A.mine
sbdp,考场上写的巨麻烦不过还是能A的(虽然MLE了……每一维都少开1就A掉了555)。设$dp[i][j][k]$为枚举到第i位,第i位是j,第i-1位是k的方案数。j和k都是0~3的整数,分别代表有前后几个雷/就是雷。
然后大力分类讨论即可
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e6+;
typedef long long ll;
const ll mod=1e9+;
char s[N];
int str[N];
ll dp[N][][];//到第i位 第i位是j 第i-1位是k
//0 0
//1 1
//2 2
//3 *
int len;
void mmod(ll &x)
{
while(x>=mod)x=x-mod;
}
bool isbomb(int x)
{
if(str[x]==||str[x]==)return ;
return ;
}
bool judge()
{
for(int i=;i<=len;i++)
{
if(str[i]==)continue;
if(str[i]==&&(str[i-]==||(str[i-]==&&str[i+]==)||(!isbomb(i-)&&!isbomb(i+))))return ;
if(str[i]==&&(!isbomb(i-)||!isbomb(i+)))return ;
}
return ;
}
int main()
{
scanf("%s",s+);len=strlen(s+);
for(int i=;i<=len;i++)
if(s[i]=='')s[i-]=s[i+]='*';
if(len==)
{
if(s[]=='*'||s[]=='')puts("");
else puts("");
return ;
}
for(int i=;i<=len;i++)
{
if(s[i]=='')str[i]=;
else if(s[i]=='')str[i]=;
else if(s[i]=='')str[i]=;
else if(s[i]=='*')str[i]=;
else if(s[i]=='?')str[i]=;
}
if(!judge())
{
puts("");
return ;
}
if(str[]!=)
{
if(str[]==)dp[][][]=;
else if(str[]==)dp[][][]=;
else if(str[]==)dp[][][]=;
}
else dp[][][]=dp[][][]=dp[][][]=;
for(int i=;i<=len;i++)
{
// cout<<str[i]<<endl;
if(str[i]==||str[i]==)
{
mmod(dp[i][][]+=dp[i-][][]);
mmod(dp[i][][]+=(dp[i-][][]+dp[i-][][]));
}
if(str[i]==||str[i]==)
{
mmod(dp[i][][]+=dp[i-][][]+dp[i-][][]+dp[i-][][]);
mmod(dp[i][][]+=dp[i-][][]+dp[i-][][]);
mmod(dp[i][][]+=dp[i-][][]);
}
if(str[i]==||str[i]==)
{
mmod(dp[i][][]+=dp[i-][][]+dp[i-][][]+dp[i-][][]);
}
if(str[i]==||str[i]==)
{
mmod(dp[i][][]+=dp[i-][][]+dp[i-][][]);
mmod(dp[i][][]+=dp[i-][][]);
mmod(dp[i][][]+=dp[i-][][]+dp[i-][][]+dp[i-][][]);
}
}
ll ans=;
if(str[len]!=&&str[len-]!=)ans=dp[len][str[len]][str[len-]];
else if(str[len]==&&str[len-]!=)
{
for(int i=;i<=;i++)
{
int j=str[len-];
if(i==&&(j==||j==))continue;
if(i==&&(j!=))continue;
if(i==)continue;
if(i==&&j==)continue;
mmod(ans+=dp[len][i][str[len-]]);
}
}
else if(str[len]!=&&str[len-]==)
{
for(int j=;j<=;j++)
{
int i=str[len];
if(i==&&(j==||j==))continue;
if(i==&&(j!=))continue;
if(i==)continue;
if(i==&&j==)continue;
mmod(ans+=dp[len][str[len]][j]);
}
}
else
{
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
if(i==&&(j==||j==))continue;
if(i==&&(j!=))continue;
if(i==)continue;
if(i==&&j==)continue;
mmod(ans+=dp[len][i][j]);
}
}
cout<<ans<<endl;
return ;
}
一开始那个$judge()$是判不合法情况。A掉之后突然发现我的程序好像遇到一开始就不合法的情况还是会有方案,所以特判了一下。
B.water
一个块的最终高度(初始高度+积水高度)就是从这个块走出矩形的路径上最大值的最小值,即把路径定义为权值取max而非权值和后的最短路。那么就直接相邻块建图,边界块都连到一个源点上,之后从源点跑dj即可。有点像网络流。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<map>
#define pa pair<int,int>
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
const int N=,M=;
const int dx[]={,,,-},
dy[]={,,-,};
int n,m;
int a[N][N];
int to[M],nxt[M],head[M],len[M],tot;
void add(int x,int y,int z)
{
to[++tot]=y;
nxt[tot]=head[x];
len[tot]=z;
head[x]=tot;
}
int id(int i,int j){return (i-)*m+j;}
int dis[M],vis[M];
void dj(int s)
{
memset(dis,0x3f,sizeof(dis));
priority_queue<pa> q;
dis[s]=;q.push(make_pair(,s));
while(!q.empty())
{
int x=q.top().second;q.pop();
if(vis[x])continue;
vis[x]=;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(dis[y]>max(dis[x],len[i]))
{
dis[y]=max(dis[x],len[i]);
q.push(make_pair(-dis[y],y));
}
}
}
} int main()
{
n=read();m=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
a[i][j]=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
for(int k=;k<;k++)
{
int nx=i+dx[k],ny=j+dy[k];
if(nx<||nx>n||ny<||ny>m)add(n*m+,id(i,j),max(a[i][j],)),add(id(i,j),n*m+,max(a[i][j],));
else add(id(i,j),id(nx,ny),max(a[i][j],a[nx][ny]));
}
}
dj(n*m+);
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
printf("%d ",dis[id(i,j)]-a[i][j]);
putchar('\n');
}
return ;
}
C.gcd
披着数据结构题的毒瘤数论。
需要维护三个量:
$f[]$:选中集合中gcd为i的数对个数
$g[]$:选中集合中gcd为i的倍数的数对个数
$s[]$:选中集合中i的倍数的个数
首先$s[]$的值是很好得到的,每次加入数时枚举它的因子$i$,$s[i]++$即可。
那$s[]$的意义何在呢?它可以帮助我们快速得到$g[]$。显然$g[i]=C_{s[i]}^2$。
又因为$g[i]=\sum \limits_{i|d} f[d]$,可以用第二类莫比乌斯反演得到:
$f[i]=\sum \limits_{i|d} \mu (\frac{d}{i}) g[d]$
$f[1]$即为所求,所以每次更改选中状态时枚举更改的数的因子,更新它的$s[]$,进而更新它的$g[]$。
ans可以通过减去原来的g再加上新g得到。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=,M=;
int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch))x=x*+ch-'',ch=getchar();
return x*f;
}
typedef long long ll;
bool vis[M];
int pr[M],tot,mu[M];
void ini()
{
mu[]=;
for(int i=;i<=M-;i++)
{
if(!vis[i])pr[++tot]=i,mu[i]=-;
for(int j=;j<=tot&&i*pr[j]<=M-;j++)
{
vis[i*pr[j]]=;
if(i%pr[j])mu[i*pr[j]]=-mu[i];
else
{
mu[i*pr[j]]=;
break;
}
}
}
}
int n,m;
int s[M],ctrl[N],a[N];
int main()
{
n=read();m=read();
ini();
for(int i=;i<=n;i++)
a[i]=read();
ll ans=;
while(m--)
{
int x=read();
for(int i=;i*i<=a[x];i++)
{
if(a[x]%i==)
{
if(!ctrl[x])ans+=1LL*mu[i]*s[i];
else ans-=1LL*(s[i]-)*mu[i];
if(ctrl[x])s[i]--;
else s[i]++;
if(i*i==a[x])continue;
if(!ctrl[x])ans+=1LL*mu[a[x]/i]*s[a[x]/i];
else ans-=1LL*(s[a[x]/i]-)*mu[a[x]/i];
if(ctrl[x])s[a[x]/i]--;
else s[a[x]/i]++;
}
}
ctrl[x]^=;
printf("%lld\n",ans);
}
return ;
}
[NOIP模拟23]题解的更多相关文章
- noip模拟23[联·赛·题]
\(noip模拟23\;solutions\) 怎么说呢??这个考试考得是非常的惨烈,一共拿了70分,为啥呢 因为我第一题和第三题爆零了,然后第二题拿到了70分,还是贪心的分数 第一题和第二题我调了好 ...
- [考试总结]noip模拟23
因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 「题解」NOIP模拟测试题解乱写II(36)
毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...
- HZOJ 20190818 NOIP模拟24题解
T1 字符串: 裸的卡特兰数题,考拉学长讲过的原题,就是bzoj3907网格那题,而且这题更简单,连高精都不用 结论$C_{n+m}^{n}-C_{n+m}^{n+1}$ 考场上10min切掉 #in ...
- 「题解」NOIP模拟测试题解乱写I(29-31)
NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...
- HGOI NOIP模拟4 题解
NOIP国庆模拟赛Day5 题解 T1 马里奥 题目描述 马里奥将要参加 NOIP 了,他现在在一片大陆上,这个大陆上有着许多浮空岛,并且其中一座浮空岛上有一个传送门,马里奥想要到达传送门从而前往 N ...
- [NOIP模拟13]题解
A.矩阵游戏 其实挺水的? 考场上根本没有管出题人的疯狂暗示(诶这出题人有毛病吧这么简单的东西写一大堆柿子),而且推公式能力近乎没有,所以死掉了. 很显然乘法有交换率结合率所以操作顺序对最终结果没什么 ...
- 8.3 NOIP 模拟12题解
话说这次考试T1和T2是真的水,然而T1CE,T2TLE,T3CE 这不就是在侮辱我的智商啊!之前本机编译都是c++,以后要用c++11. 这次的T1就是一个大型找规律,我的规律都找出来了,但是竟然用 ...
随机推荐
- Codeforces 789e The Great Mixing (bitset dp 数学)
Sasha and Kolya decided to get drunk with Coke, again. This time they have k types of Coke. i-th typ ...
- 【Flutter学习】页面布局之宽高尺寸处理
一,概述 Flutter中拥有30多种预定义的布局widget,常用的有Container.Padding.Center.Flex.Row.Colum.ListView.GridView.按照< ...
- flask-sqlalchemy报错 Object '<User at xxxx>' is already attached to session '1' (this is '2')
报错: Object '<User at xxxx>' is already attached to session '1' (this is '2') 结论: 两个不同的db ...
- fedora 25重新安装引导
引导区被其他系统给覆盖了,重新安装引导 grub2-install /dev/sdb GRUB_SAVEDEFAULT=true BIOS grub2-mkconfig -o /boot/grub2/ ...
- mysql的时间存储格式
虽然mysql提供了datatime和timestamp两种存储时间的格式,但是如果设计较多计算,应存INT(11)类型.
- 响应式web开发的一些文章
CSS Device Adaptation:关注 W3C 建议的 CSS 设备适配标准. “在 CSS 中使用 LESS 实现更多的功能”(作者:Uche Ogbuji,developerWorks, ...
- export export-default import 使用场景
export export-default import 使用场景:https://blog.csdn.net/weixin_36222137/article/details/77453774
- jumpserver3.0页面配置
一.jumpserver的启动 1 2 Jumpserver的启动和重启 [root@test-vm001 install]# /opt/jumpserver/service.sh start/res ...
- python-模块-包
一 模块 1 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编 ...
- document.createDocumentFragment()的用法
createDocumentFragment有什么作用呢? 调用多次document.body.append(),每次都要刷新页面一次.效率也就大打折扣了,而使用document_createDocu ...