「2019.7.22 考试」AC和WA0一步之遥
这卷子还是答的挺惨的。
第一题5min写完了,自认为AC(其实WA了80),第二题推了半天CRT的公式老出错结果发现是程序打错了。第三题打模拟150行结果数组没开够,开大就是0->60的转变。状态很差,坏肚子了,一直在去厕所,看来下次早起要吃点素的了。
题解:
T1方程的解。
发现就是个exgcd,先求出gcd和顺带的特解 $ x_0 y_0 $
设 $ gcd(a,b)=d $
这个时候用个通解公式:
$ x=x_0 \frac{c}{d} + k \frac{b}{d} $
$ y=y_0 \frac{c}{d} - k \frac{a}{d} $
那么我们发现方程解的个数就是k的个数。
解个不等式组:
$ x>0 $
$ y>0 $
得到:
$ y_0 \frac{c}{a} < k <-x_0 \frac{c}{b} $
左边向下取整得到l,右边向上去整得到r。
答案个数就是r-l+1,没必要暴力枚举验证啥的,稍low。
加特判就AC,顺提这特判真恶心。
T2 visit
一眼数学题很准,式子推错了没办法。
先说一下错解,大概是分的不太明确,没有把同类分到一组。
设d=T-n-m。
首先d>0并且2|d有解:
我是按照到 $ (n,m) $ 的有效步和无效步算的,这样的话我推出来得式子就是:
$ C_T^{n+m} C_{n+m}^n \sum \limits_{i=0,2|i}^d (C_d^i C_i^{\frac{i}{2}} C_{d-i}^{\frac{d-i}{2}}) $
看一看他什么意思,我把有效的n+m步从T步里分了出来,然后把n步向上的从n+m步中分离开。
剩下的就是d步中的上下左右插空,可以枚举上下走的步数,是i,可以证明他必然是偶数,然后这些步子中必然有 $ \frac{i}{2} $ 步向上,在i步中选出相应的位置,剩下左右走的也可以选出相应的位置。
我们看一下他哪里有问题,问题在于,前面分出来的n步中,是向上走的,他等同于无效步中向上走的步,但是却被我分开计算了。
导致解变多。
正解的话还简单一点,按照方向分布,这样不会出现和我一样的问题。
也就是:
$ \sum \limits_{d=n}^{T-m} C_T^d C_d^{\frac{d-n}{2}} C_{T-d}^{\frac{T-d-m}{2}} $
还是比较简单的,不赘述。
式子出来之后就只剩下板子了,质数小就Lucas算一下,质数多就CRT合并一下,解决了。
T3的话是个大模拟。
一些推论:
1.一个方向上的格子奇偶性不变,所以一个格子最多被从两个相反方向的光射入。
2.黑格子很少,一次循环中反射的次数和n,m,k线性相关。
3.每一条主对角线和副对角线都有一个特殊的编号,可以用x+y和x-y+m来编号。
4.每个格子在一次循环里最多被射两次,只需要记录是否存在反向操作,有的话答案除2。
可以通过坐标二分查找到转角处。
程序写的时候其实可以只写一个判断方向的函数,用这个函数找到他前面的格子,左边的格子和右边的格子,然后用pair存一下,换个函数只需要判断左转右转还是反向,只需要写左转右转反向的函数了,看起来多不过很好水。
那就这么多。
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
ll T,a,b,c,x,y;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==)
{
x=;y=;
return a;
}
ll d=exgcd(b,a%b,x,y);
ll tmp=x;
x=y;
y=tmp-a/b*y;
return d;
}
int main()
{
scanf("%lld",&T);
while(T--)
{
scanf("%lld%lld%lld",&a,&b,&c);
ll d=exgcd(a,b,x,y);
ll l=floor(1.0*c/b*(-x)),r=ceil(1.0*c/a*y);
ll k=r-l-;
if(a==&&b==)
{
if(c==)
{
puts("ZenMeZheMeDuo");
continue;
}
else
{
puts("");
continue;
}
}
if((c%d))
{
puts("");
continue;
}
if(1LL*a*b<)
{
puts("ZenMeZheMeDuo");
continue;
}
if(a==)
{
if(1LL*b*c>) puts("ZenMeZheMeDuo");
else puts("");
continue;
}
if(b==)
{
if(1LL*a*c>) puts("ZenMeZheMeDuo");
else puts("");
continue;
}
if(k<)
{
puts("");
continue;
}
if(k>) puts("ZenMeZheMeDuo");
else printf("%lld\n",k);
}
return ;
}
方程的解
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=2e5+;
ll T,mod,n,m,s,fac[maxn],inv[maxn],p[],ans[];
ll qw(ll a,ll b,ll ml)
{
ll ans=;
for(;b;b>>=,a=a*a%ml) if(b&) ans=ans*a%ml;
return ans;
}
void moddivide()
{
ll mm=mod;
for(int i=;1LL*i*i<=mm;i++)
if(mm%i==)
{
p[++s]=i;
mm/=i;
}
if(mm>) p[++s]=mm;
}
ll CRT()
{
ll b=;
for(int i=;i<=s;i++)
{
ll M=mod/p[i];
b+=ans[i]*M%mod*qw(M,p[i]-,p[i])%mod;
b%=mod;
}
return b;
}
void Getfac_inv(int p)
{
fac[]=inv[]=;
for(int i=;i<=min(T,(ll)p);i++)
{
fac[i]=fac[i-]*i%p;
inv[i]=qw(fac[i],p-,p);
}
}
ll Get_C(ll n,ll m,ll mod)
{
if(n<m) return ;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
ll lucas(ll n,ll m,ll p)
{
if(m==) return ;
return Get_C(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
}
int main()
{
scanf("%lld%lld",&T,&mod);
scanf("%lld%lld",&n,&m);
n=abs(n);m=abs(m);
int d=T-n-m;
if(d<||(d&))
{
puts("");
return ;
}
moddivide();
ll aa;
for(int j=;j<=s;j++)
{
Getfac_inv(p[j]);
aa=;
for(int i=n;i<=T-m;i+=)
{
ll tmp=lucas(T,i,p[j])*lucas(i,(i-n)/,p[j])%p[j]*lucas(T-i,(T-i-m)/,p[j])%p[j];
aa+=tmp;
aa%=p[j];
}
ans[j]=aa;
}
printf("%lld\n",CRT());
return ;
}
visit
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#include<map>
#define mr(a,b) make_pair(a,b)
using namespace std;
typedef long long ll;
const int ne=,se=,sw=,nw=,maxn=1e5+,tmp=maxn+;
const int xi[]={,-,+,+,-},yi[]={,+,+,-,-};
vector<int> man[maxn<<],rst[maxn<<];
map<ll,int> mp;
map<pair<int,pair<int,int> >,int> up;
int n,m,k,x,y,sx,sy,nx,ny,fr,dr,flag;
ll ans;
char s[];
int jud()
{
if(s[]=='N'&&s[]=='E') return sw;
if(s[]=='N'&&s[]=='W') return se;
if(s[]=='S'&&s[]=='E') return nw;
if(s[]=='S'&&s[]=='W') return ne;
}
int right(int x)
{
if(x==ne) return se;
if(x==se) return sw;
if(x==sw) return nw;
if(x==nw) return ne;
}
int left(int x)
{
if(x==ne) return nw;
if(x==nw) return sw;
if(x==sw) return se;
if(x==se) return ne;
}
int ni(int x)
{
if(x==ne) return sw;
if(x==se) return nw;
if(x==sw) return ne;
if(x==nw) return se;
}
int lt(int &x,int &y,int dir)
{
if(dir==se) y++;
if(dir==ne) x--;
if(dir==sw) x++;
if(dir==nw) y--;
}
int rt(int &x,int &y,int dir)
{
if(dir==se) x++;
if(dir==ne) y++;
if(dir==sw) y--;
if(dir==nw) x--;
}
int change(pair<int,pair<int,int> > d,int dir,int &x,int &y)
{
int a=d.first,b=d.second.first,c=d.second.second;
if(a)
{
if(b&&c)
{
flag=;
return ni(dir);
}
if((!b)&&c)
{
lt(x,y,dir);
return left(dir);
}
if(b&&(!c))
{
rt(x,y,dir);
return right(dir);
}
if((!b)&&(!c))
{
flag=;
return ni(dir);
}
}
else
{
x+=xi[dir];y+=yi[dir];
return dir;
}
}
pair<int,pair<int,int> > gnum(int x,int y,int dir)
{
pair<int,pair<int,int> > a;
if(dir==sw)
{
a.first=mp[1LL*(x+)*tmp+y-];
a.second.first=mp[1LL*(x+)*tmp+y];
a.second.second=mp[1LL*x*tmp+y-];
}
if(dir==nw)
{
a.first=mp[1LL*(x-)*tmp+y-];
a.second.first=mp[1LL*tmp*x+y-];
a.second.second=mp[1LL*tmp*(x-)+y];
}
if(dir==ne)
{
a.first=mp[1LL*(x-)*tmp+y+];
a.second.first=mp[1LL*(x-)*tmp+y];
a.second.second=mp[1LL*x*tmp+y+];
}
if(dir==se)
{
a.first=mp[1LL*(x+)*tmp+y+];
a.second.first=mp[1LL*x*tmp+y+];
a.second.second=mp[1LL*(x+)*tmp+y];
}
return a;
}
pair<int,int> find(int x,int y,int r)
{
if(r==ne)
{
int t=lower_bound(rst[x+y].begin(),rst[x+y].end(),x)-rst[x+y].begin()-;
t=rst[x+y][t]+;
return mr(t,x+y-t);
}
if(r==se)
{
int t=lower_bound(man[x-y+m+].begin(),man[x-y+m+].end(),x)-man[x-y+m+].begin();
t=man[x-y+m+][t]-;
return mr(t,-(x-y-t));
}
if(r==sw)
{
int t=lower_bound(rst[x+y].begin(),rst[x+y].end(),x)-rst[x+y].begin();
t=rst[x+y][t]-;
return mr(t,x+y-t);
}
if(r==nw)
{
int t=lower_bound(man[x-y+m+].begin(),man[x-y+m+].end(),x)-man[x-y+m+].begin()-;
t=man[x-y+m+][t]+;
return mr(t,-(x-y-t));
}
}
void work(int x,int y,int dr)
{
for(int i=;i<=;i++)
if(dr==i)
{
pair<int,int> nxt=find(x,y,i);
ans+=abs(nxt.first-nx)+;
nx=nxt.first;ny=nxt.second;
return ;
}
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
while(k--)
{
scanf("%d%d",&x,&y);
man[x-y+m+].push_back(x);
rst[x+y].push_back(x);
mp[1LL*x*tmp+y]=;
}
for(int i=;i<=m;i++)
{
mp[*tmp+i]=;mp[1LL*tmp*(n+)+i]=;
man[-i+m+].push_back();
rst[+i].push_back();
man[n+-i+m+].push_back(n+);
rst[n+i+].push_back(n+);
}
for(int i=;i<=n;i++)
{
mp[1LL*i*tmp+]=;mp[1LL*i*tmp+m+]=;
man[i-+m+].push_back(i);
rst[i+].push_back(i);
man[i-m-+m+].push_back(i);
rst[i+m+].push_back(i);
}
mp[]=;mp[1LL*tmp*(n+)+]=;mp[1LL**tmp+m+]=;mp[1LL*tmp*(n+)+m+]=;
man[-+m+].push_back();
rst[+].push_back();
man[n+-+m+].push_back(n+);
rst[n++].push_back(n+);
man[-m-+m+].push_back();
rst[+m+].push_back();
man[n+-m-+m+].push_back(n+);
rst[n++m+].push_back(n+);
for(int i=;i<=max(n,m)*+;i++) sort(man[i].begin(),man[i].end());
for(int i=;i<=max(n,m)*+;i++) sort(rst[i].begin(),rst[i].end());
scanf("%d%d",&sx,&sy);
scanf("%s",s+);
nx=sx;ny=sy;fr=dr=jud();
work(nx,ny,dr);
pair<int,pair<int,int> > dd=gnum(nx,ny,dr);
dr=change(dd,dr,nx,ny);
sx=nx;sy=ny;fr=dr;
ans=;
do
{
work(nx,ny,dr);
pair<int,pair<int,int> > dd=gnum(nx,ny,dr);
dr=change(dd,dr,nx,ny);
}while(!(nx==sx&&ny==sy&&dr==fr));
printf("%lld\n",ans>>flag);
return ;
}
light
「2019.7.22 考试」AC和WA0一步之遥的更多相关文章
- 「2019.8.11 考试」一套把OI写的很诗意的题
这次写的更惨了,T2暴力再次挂掉了. 先写了T1的75暴力,然后写了T2的70分暴力(挂成了25),T3啥也不会骗了12分.T3看完题一点思路没有,心态爆炸了,一直在观察数据,忽略的思考的重要性,以至 ...
- 「2019.8.9 考试」神仙的dp总让人无所适从
T1是个容斥,我掐手指一算他为了卡容斥的正确性,绝不会把n和m出的很相近($O(n^2)$算法在nm相等的时候达到最高时间复杂度),不然就太好做了,于是开了特判+各种卡常和滚动数组优化,卡到了70分, ...
- 「kuangbin带你飞」专题十七 AC自动机
layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...
- 开发者的瑞士军刀「GitHub 热点速览 v.22.04」
Swiss Army knife 可以说是本周的关键词了,多个项目采用该词来描述它的特性:像是能全方位解决浏览器"网络"操作的 CyberChef 方便你进行数据加密.解编码,还有 ...
- GitHub 毕业年鉴「GitHub 热点速览 v.22.20」
GitHub 毕业需要什么呢?一个 PR!那么提交一个 PR 需要什么?也许你是使用终端命令来提交 git 操作的,那么你可以了解下 Bash-Oneliner,收录了大量好用的 bash 命令,虽然 ...
- WAIC | 奇点云携「酷炫AI应用」亮相2019世界人工智能大会
你是否还在疑惑“人工智能可否改变世界?” 那么,你该有一些危机感了. 机器视觉.自然语言处理.智能语音.机器人问诊.智慧驾驶……这些AI技术及应用早已渗入了我们日常生活的点滴. 29日,以「智联世界, ...
- 读 Linux 像读小说「GitHub 热点速览 v.22.03」
本周特推选取了一个画风有点意思的 Linux 代码带读项目 flash-linux0.11-talk,希望有趣的文风能带你读完 Linux 代码.当然画风可以增加阅读体验,彩色标记也是一种学习方法-- ...
- 火爆的文字游戏你玩了吗?「GitHub 热点速览 v.22.06」
不知道你有没有被 Wordle 这款游戏刷屏,在本期热点速览的特推部分选了一个 React 编写的开源版本同你分享,而本次公众号摘要也是一个提示, 只不过这个只能盲猜了.别小瞧 Wordle 这个游戏 ...
- 程序员的情人节「GitHub 热点速览 v.22.07」
又是一年情人日,刚好还是发文的今天.也没什么好送的,送点程序员的浪漫--代码和开源项目吧.记得在本周特推查收这份来自程序员的独有浪漫. 本周 GitHub 霸榜的项目基本上都是老项目,从老项目中挖点新 ...
随机推荐
- Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门
1. 什么是响应式编程 在计算机中,响应式编程或反应式编程(英语:Reactive programming)是一种面向数据流和变化传播的编程范式.这意味着可以在编程语言中很方便地表达静态或动态的数据流 ...
- JVM Java字节码的角度分析switch的实现
目录 Java字节码的角度分析switch的实现 引子 前置知识 一个妥协而又枯燥的方案 switch的实现 回顾历史 字节码分析 其他实现方式? Java字节码的角度分析switch的实现 作者 k ...
- 详述Python序列化
一.前言 1. 现实需求 每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Python也是一样.很多时候我们会有这样的需求: 把内存中的各种数据类型的 ...
- Linux内存描述之内存节点node–Linux内存管理(二)
日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDrivers Linux内存管理 #1 ...
- django rest framework1
内容回顾: 1.开发模式 - 普通开发方式(前后端放在一起写) - 前后端分离 2.后端开发 为前端提供URL(API/接口的开发) 注:永远返回HttpResponse 3.Django FBV.C ...
- 用 Sphinx 搭建博客时,如何自定义插件?
之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建. 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清 ...
- Redis学习三(进阶功能).
一.排序 redis 支持对 list,set 和 zset 元素的排序,排序的时间复杂度是 O(N+M*log(M)).(N 是集合大小,M 为返回元素的数量) sort key [BY patte ...
- Spring Boot Actuator 整合 Prometheus
简介 Spring Boot 自带监控功能 Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况.Bean加载情况.环境变量.日志信息.线程信息等.这一节结合 Prometheus .G ...
- Android Studio 模拟器Intel 加速
Starting emulator for AVD 'Phone1'emulator: ERROR: x86 emulation currently requires hardware acceler ...
- win-socket
WIN32平台上的WINSOCK编程都要经过下列步骤: 定义变量->获得WINDOCK版本->加载WINSOCK库->初始化->创建套接字->设置套接字选项->关闭 ...