7.22 NOIP模拟7
又是炸掉的一次考试
T1.方程的解
本次考试最容易骗分的一道题,但是由于T2花的时间太多,我竟然连a+b=c都没判。。暴力掉了40分。
首先a+b=c,只有一组解。
然后是a=1,b=1,答案是c-1,不解释。
对于最大的数据,我们可以用exgcd求出一组特解,之后的通解为x+(b/gcd)*k, y+(a/gcd)*k.
求出正整数解的个数即可。
注意有很多特判,慢慢调试就好(改这题的时间比我改T3的时间都长)
#include<bits/stdc++.h>
#define m 65535
#define int long long
using namespace std;
int t,a,b,c,x,y;
long long ans;
int exgcd(int a,int b,int &x,int &y)
{
if(b==)
{
x=,y=;
return a;
}
int gcd=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return gcd;
}
main()
{
scanf("%lld",&t);
while(t--)
{
ans=;
scanf("%lld%lld%lld",&a,&b,&c);
if(a+b==c&&a>=&&b>=)
{
puts("");
continue;
}
if(a<&&b<&&c<)
a=-a,b=-b,c=-c;
if(a==&&b==)
{
ans=c-;
if(ans>&&ans<=)
{
printf("%lld\n",ans);
continue;
}
if(ans<=)
puts("");
if(ans>m)
puts("ZenMeZheMeDuo");
continue;
}
if(t<=&&a<=&&a>=&&b<=&&b>=&&c>=&&c<=)
{
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
if(a*i+b*j>c)break;
if(a*i+b*j==c)ans++;
}
if(ans>m)puts("ZenMeZheMeDuo");
else printf("%lld\n",ans);
continue;
}
if(a==&&b==)
{
if(c==)puts("ZenMeZheMeDuo");
else puts("");
continue;
}
if(a==)
{
if(b>)
{
if(c>&&(!(c%b)))puts("ZenMeZheMeDuo");
else puts("");
}
if(b<)
{
if(c<&&(!(c%b)))puts("ZenMeZheMeDuo");
else puts("");
}
continue;
}
if(b==)
{
if(a>)
{
if(c>&&(!(c%a)))puts("ZenMeZheMeDuo");
else puts("");
}
if(a<)
{
if(c<&&(!(c%a)))puts("ZenMeZheMeDuo");
else puts("");
}
continue;
}
if((a<&&b<&&c>=)||(a>&&b>&&c<=))
{
puts("");
continue;
}
if(a<&&b<&&c<)
a=-a,b=-b,c=-c;
int gcd=exgcd(a,b,x,y);
if(c%gcd)
{
puts("");
continue;
}
if(a*b<)
{
puts("ZenMeZheMeDuo");
continue;
}
int k=c/gcd,xx=b/gcd,yy=a/gcd;
x*=k,y*=k;
if(xx<)
xx=-xx,yy=-yy;
if(x<=)
{
int xxx=x/xx+;
x+=xxx*xx,y-=yy*xxx;
}
if(y<=)
{
int xxx=y/yy+;
x-=xx*xxx,y+=yy*xxx;
}
while(x<=)
x+=xx,y-=yy;
while(y<=)
x-=xx,y+=yy;
if(!x||!y)
{
puts("");
continue;
}
if(x/y<||y/x<)
{
puts("");
continue;
}
int aa=x/xx+,bb=y/yy+;
if(!(x%xx))aa--;
if(!(y%yy))bb--;
ans=max(aa,bb);
if(ans>m)puts("ZenMeZheMeDuo");
else printf("%lld\n",ans);
}
return ;
}
T2.visit
本场考试最可惜的一道题,打出正解,却因为答案为0的特判wa(改一个字符,70分->AC)
考试的时候先打了个n^3dp,然后开始找规律
10,5,5 = C(10,5)*C(10,0);
10,4,4 = C(10,5)*C(10,1); 10,4,6=C(10,4)*C(10,0);
10,3,3 = C(10,5)*C(10,2); 10,3,5=C(10,4)*C(10,1); 10,3,7=C(10,3)*C(10,0);
10,2,2 = C(10,5)*C(10,3); 10,2,4=C(10,4)*C(10,2); 10,2,6=C(10,3)*C(10,1); 10,2,8=C(10,2)*C(10,0);
10,1,1 = C(10,5)*C(10,4);
10,0,0 = C(10,5)*C(10,5);
这个表我没有打完,但是我感觉已经很显然了,ans=C(t,(t-n-m)/2)*C(t,(t-n+m)/2);(n>m)
注意特判无解情况,t-n-m为奇数时,必然无解。
然后我终于理解了数据范围最后,mod为若干质数乘积的意思。。。
恩,然后我就开始手推crt,码码码,大概一个小时调完了,和dp对了几个点,感觉没啥问题,没打对拍放心的去看T3了。
考后发现自己打了个这个:
if(((t%(n+m))&))
{
puts("");
return ;
}
???????????我干了啥?把%改成-,AC。一个特判卡掉30分,我。。。。
至于组合数的解释,请参考其他人的题解。(其实是我不会解释)
#include<cstdio>
#include<cmath>
using namespace std;
inline int read(){
register int ss=;register char bb=getchar();
while(bb<||bb>)bb=getchar();
while(bb>=&&bb<=)ss=(ss<<)+(ss<<)+(bb^),bb=getchar();
return ss;
}
inline long long power(long long x,int y,int const mod){
long long ans=;
for(;y;y>>=,x=(x<<)%mod)
if(y&)ans=(ans+x)%mod;
return ans;
}
int const t=read(),p=read();
int n,m,tot;
long long prime[],f[],invv[];
inline void split(long long x,int lit){
for(register int i=;i<=lit && x^;++i)
if(!(x%i))prime[++tot]=i,x/=i;
if(x^)prime[++tot]=x;
return ;
}
long long exgcd(long long a,long long b,long long &x,long long &y){
if(!b)return x=,y=,;
long long z=exgcd(b,a%b,x,y),lh=x;
x=y,y=lh-a/b*y;
return z;
}
inline long long inv(long long x,long long mod){
long long a,b,c=exgcd(x,mod,a,b);
if(c^)return -;
if(a<)a=a%mod+mod;
return a;
}
inline long long cp(long long x,long long y,long long const mod){
if(x<y)return ;
if(!y || x==y)return ;
if(y>x-y)y=x-y;
long long a=,b=;
for(register int i=;i<y;++i)
a=a*(x-i)%mod,b=b*(y-i)%mod;
return a*inv(b,mod)%mod;
}
long long lucas(long long x,long long y,long long mod){
if(x<y)return ;
if(x==y)return ;
return y?cp(x%mod,y%mod,mod)*lucas(x/mod,y/mod,mod)%mod:;
}
inline long long china(){
long long ans=;
for(register int i=;i<=tot;++i)
ans=(ans+power(p/prime[i],power(invv[i],f[i],p),p))%p;
return ans;
}
inline long long cq(int x,int y){
for(register int i=;i<=tot;++i)
f[i]=lucas(x,y,prime[i]);
return china();
}
inline void swap(int &x,int &y){
int z=x;
x=y,y=z;
return ;
}
signed main(){
n=read(),m=read();
if(n<m)swap(n,m);
split(p,sqrt(p));
for(register int i=;i<=tot;++i)
invv[i]=inv(p/prime[i],prime[i]);
printf("%lld",cq(t,t-n+m>>)*cq(t,t-n-m>>)%p);
return ;
}
这是remarkable的代码
T3.光
没想到一道模拟题卡掉了我50分。。。暴力都打错了,骗到20分,考完后发现加clock等一大堆特判可以卡到80分。
正解就是模拟,但是优化了一下。首先,在原来的基础上,可以直接考虑到当前状态的终点:二分。
在同一种状态中,横纵坐标之和或差必然不变,因此我们可以将黑块存进保存坐标之和或差的vector中,给每个vector排序后二分。
但是我们似乎忽略了一个问题:如何统计答案?
一个非常简单却不好想的结论:若一个块被经过,则光线必然只穿过他的一条对角线。
证明如下:
我们给每两个相邻的方块染上不同的颜色,则同一种状态的光线只经过同种颜色的方块。而除了反向反射的两种状态,另外两种反射方式必然从一种颜色的方块变成另一种,即,经过右下->左上对角线和右上->左下对角线的光线穿过的方块颜色必不相同,所以同一方块不可能被穿过两条对角线。
既然如此,那么就又有一个非常显然的结论:一个方块最多被经过两次,两次穿过同一对角线且方向相反。
那么一个方块被经过两次的条件呢?当且仅当发生了反向的反射。同样,若发生了反向的反射,反向光线会将原光线的所有路径重走一遍,因此,一旦发生反向反射,所有被经历的方块都会被穿过两次。否则,每个方块仅被穿过一次。
因此,我们可以记录是否发生了反向的反射,若发生了,最后统计的答案数/2。计算每种状态的贡献时,只需将起始节点和终点的横(纵)坐标相减即可。
注意反射情况十分复杂,分类讨论即可。为了方便,多调几个STL挺好的。
#include<bits/stdc++.h>
#define mk(a,b,c) mp(a,mp(b,c))
#define mp(a,b) make_pair(a,b)
#define pb push_back
using namespace std;
int n,m,k;
long long ans=;
bool v;
vector<int>h[],g[];
map<pair<int,pair<int,int> >,bool>c;
map<pair<int,int>,bool>kk;
int main()
{
scanf("%d%d%d",&n,&m,&k);int kkk=max(n,m);
for(int i=;i<=k;i++)
{
int x,y;
scanf("%d%d",&x,&y);
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
}
for(int i=,x,y;i<=m+;i++)
{
x=,y=i;
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
x=n+;
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
}
for(int i=,x,y;i<=n+;i++)
{
x=i,y=;
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
y=m+;
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
}
for(int i=;i<=kkk+kkk+;i++)
sort(h[i].begin(),h[i].end()),
sort(g[i].begin(),g[i].end());
int x,y,zt,i=;
string ss;
cin>>x>>y>>ss;
if(ss=="NE")zt=;
if(ss=="NW")zt=;
if(ss=="SE")zt=;
if(ss=="SW")zt=;
while(!c[mk(x,y,zt)])
{
c[mk(x,y,zt)]=true;i++;
if(zt==)
{
int cc=*--upper_bound(h[x+y].begin(),h[x+y].end(),x-y),
xx=(x+y+cc)>>,yy=(x+y-cc)>>;
if(i^)ans+=abs(x-xx);
if((kk[mp(xx+,yy)]&&kk[mp(xx,yy-)])
||(!kk[mp(xx+,yy)]&&!kk[mp(xx,yy-)]))
{
zt=,x=xx+,y=yy-;
if(i^)v=true;
}
else if(kk[mp(xx+,yy)])
zt=,x=xx,y=yy-;
else if(kk[mp(xx,yy-)])
zt=,x=xx+,y=yy;
}
else if(zt==)
{
int cc=*upper_bound(h[x+y].begin(),h[x+y].end(),x-y),
xx=(x+y+cc)>>,yy=(x+y-cc)>>;
if(i^)ans+=abs(x-xx);
if((kk[mp(xx-,yy)]&&kk[mp(xx,yy+)])
||(!kk[mp(xx-,yy)]&&!kk[mp(xx,yy+)]))
{
zt=,x=xx-,y=yy+;
if(i^)v=true;
}
else if(kk[mp(xx-,yy)])
zt=,x=xx,y=yy+;
else if(kk[mp(xx,yy+)])
zt=,x=xx-,y=yy;
}
else if(zt==)
{
int cc=*--upper_bound(g[x-y+kkk].begin(),g[x-y+kkk].end(),x+y),
xx=(x-y+cc)>>,yy=(cc-x+y)>>;
if(i^)ans+=abs(x-xx);
if((kk[mp(xx+,yy)]&&kk[mp(xx,yy+)])
||(!kk[mp(xx+,yy)]&&!kk[mp(xx,yy+)]))
{
zt=,x=xx+,y=yy+;
if(i^)v=true;
}
else if(kk[mp(xx+,yy)])
zt=,x=xx,y=yy+;
else if(kk[mp(xx,yy+)])
zt=,x=xx+,y=yy;
}
else if(zt==)
{
int cc=*upper_bound(g[x-y+kkk].begin(),g[x-y+kkk].end(),x+y),
xx=(x-y+cc)>>,yy=(cc-x+y)>>;
if(i^)ans+=abs(x-xx);
if((kk[mp(xx-,yy)]&&kk[mp(xx,yy-)])
||(!kk[mp(xx-,yy)]&&!kk[mp(xx,yy-)]))
{
zt=,x=xx-,y=yy-;
if(i^)v=true;
}
else if(kk[mp(xx+,yy)])
zt=,x=xx,y=yy-;
else if(kk[mp(xx,yy+)])
zt=,x=xx-,y=yy;
}
}
printf("%lld\n",v?ans/:ans);
return ;
}
大模拟
7.22 NOIP模拟7的更多相关文章
- 8.22 NOIP 模拟题
8.22 NOIP 模拟题 编译命令 g++ -o * *.cpp gcc -o * *.c fpc *.pas 编译器版本 g++/gcc fpc 评测环境 位 Linux, .3GHZ CPU ...
- 2018.9.22 NOIP模拟赛
*注意:这套题目应版权方要求,不得公示题面. 从这里开始 Problem A 妹子 Problem B 旅程 Problem C 老大 因为业务水平下滑太严重,去和高一考NOIP模拟,sad... P ...
- 9.22 NOIP模拟题
吉林省信息学奥赛 2017 冬令营 ...
- 2018.08.22 NOIP模拟 string(模拟)
string [描述] 给定两个字符串 s,t,其中 s 只包含小写字母以及*,t 只包含小写字母. 你可以进行任意多次操作,每次选择 s 中的一个*,将它修改为任意多个(可以是 0 个)它的前一个字 ...
- 2021.5.22 noip模拟1
这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...
- 9.22 noip模拟试题
水灾(sliker.cpp/c/pas) 1000MS 64MB 大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY ...
- 2018.08.22 NOIP模拟 shop(lower_bound+前缀和预处理)
Shop 有 n 种物品,第 i 种物品的价格为 vi,每天最多购买 xi 个. 有 m 天,第 i 天你有 wi 的钱,你会不停购买能买得起的最贵的物品.你需要求出你每天会购买多少个物品. [输入格 ...
- 2018.08.22 NOIP模拟 or(线段树)
or [描述] 构造一个长度为 n 的非负整数序列 x,满足 m 个条件,第 i 个条件为x[li] | x[li+1] | - | x[ri]=pi. [输入] 第一行两个整数 n,m.接下来 m ...
- 18.9.22 noip模拟赛
此题为找规律.期望100 实际100 #include<cstdio> #include<cstring> #include<iostream> #include& ...
随机推荐
- Docker 环境搭建(RedHat 7)
Docker 环境搭建(RedHat 7): CentOS7 下载 http://mirrors.sohu.com/centos/7/isos/x86_64/ 装载镜像文件 安装Linux 7, 参考 ...
- 【windows】远程桌面 把远程服务器的explorer.exe进程关掉了,咋办?
在操作windows2008R2服务器时不小心把explorer.exe进程关闭了,瞬间整个界面就蓝色了. 重启,做不到,各种快捷键用不了,最后发现Alt+Tab可以用,刚好打开了IIS, 打开其中一 ...
- 在vue中操作dom元素
在vue中可以通过给标签加ref属性,就可以在js中利用ref去引用它,从而达到操作该dom元素,以下是个参考例子 1 <template> 2 <div> 3 <div ...
- python编程基础之十四
列表的增加元素 l1 = [10, 20, 30] l1.append(40) # 末尾追加一个值为40的元素 l1.extend([50, 60]) # 末尾追加一系列元素,extend + 可 ...
- 使用Line Pos Info 和 Modern C++ 改进打印日志记录
使用Line Pos Info 和 Modern C++ 改进打印日志记录 使用跟踪值:不管自己是多么的精通,可能仍然使用调试的主要方法之一 printf , TRaCE, outputDebugSt ...
- Kubernetes网络插件Flannel的三种工作模式
跨主机通信的一个解决方案是Flannel,由CoreOS推出,支持3种实现:UDP.VXLAN.host-gw 一.UDP模式(性能差) 核心就是通过TUN设备flannel0实现(TUN设备是工作在 ...
- [NOIp2011] luogu P1311 选择客栈
我妈的抽象歌曲真 nb. 题目描述 给你 nnn 个点,每个点有两个参数 ci,dic_i,d_ici,di,给你一个数 DDD.定义一种方案合法,当且仅当你选出整数 i,j∈[1,n],i< ...
- 简单使用OpenSSL生成密钥
一.生成自签名证书 1.1.创建root CA私钥 openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 ...
- 高通电源管理函数的power_supply的调用关系
以msm8909为例,高通的主要文件有几个: qpnp-linear-charger.c(线性充电器) qpnp-vm-bms.c(BMS管理) power_supply_core.c(power_s ...
- Shell多进程执行任务
展示代码 #!/bin/bash trap "exec 1000>&-;exec 1000<&-;exit 0" 2 # 分别为 创建管道文件,文件操作 ...