码死了...考试的时候基本上是写一会儿思考一会儿人生....考完了调了调...最后400行+....不应该这么长的....以后重写一下再补题解.....

也许这就是蒟蒻吧.jpg

安利cstdio博客翻译的题解.

#include<cstdio>
#include<cstring>
#include<cmath>
#include<set>
using namespace std;
const int mod=1000000007;
int X,Y,K;
int ax,ay,bx,by;
int xx[20],yy[20];
set<pair<int,int> > dict;
double direc(int a,int b){
if(a!=0)return double(b)/a;
else return 1e8;
}
int check1(int a,int b){
if(X==0&&Y==0)return -1;
int step1,step2;
if(a==0){
if(X==0){
double tmp=Y/(double)(b);
if(tmp>0&&(fabs(tmp-floor(tmp))<1e-8)){
step1=tmp;
int tmpx=0,tmpy=0;
for(int i=1;i<=step1;++i){
tmpx+=a;tmpy+=b;
if(dict.find(pair<int,int>(tmpx,tmpy))!=dict.end())return 0;
}
return -1;
//step1=floor(tmp);
}else return 0;
}else return 0;
}else{
step1=X/(double)(a);
if(step1<=0||(fabs(step1-floor(step1))>1e-8))return 0;
}
if(b==0){
if(Y==0){
double tmp=X/(double)(a);
if(tmp>0&&(fabs(tmp-floor(tmp))<1e-8)){
step1=tmp;
int tmpx=0,tmpy=0;
for(int i=1;i<=step1;++i){
tmpx+=a;tmpy+=b;
if(dict.find(pair<int,int>(tmpx,tmpy))!=dict.end())return 0;
}
return -1;
}else return 0;
}else return 0;
}else{
step2=Y/(double)(b);
if(step2<=0||(fabs(step2-floor(step2))>1e-8))return 0;
}
if(step1==step2){
//blabla
int tmpx=0,tmpy=0;
for(int i=1;i<=step1;++i){
tmpx+=a;tmpy+=b;
if(dict.find(pair<int,int>(tmpx,tmpy))!=dict.end())return 0;
}
return -1;
}
else{
return 0;
}
}
int qpow(int a,int x){
int ans=1;
for(;x;x>>=1,a=a*1ll*a%mod){
if(x&1)ans=ans*1ll*a%mod;
}
return ans;
}
int check4(int a,int b){
if(X==0&&Y==0)return -1;
int step1,step2;
if(a==0){
if(X==0){
double tmp=Y/(double)(b);
if(tmp>0&&(fabs(tmp-floor(tmp))<1e-8)){
step1=tmp;
int tmpx=0,tmpy=0;
for(int i=1;i<=step1;++i){
tmpx+=a;tmpy+=b;
if(dict.find(pair<int,int>(tmpx,tmpy))!=dict.end())return 0;
}
return 1;
//step1=floor(tmp);
}else return 0;
}else return 0;
}else{
step1=X/(double)(a);
if(step1<=0||(fabs(step1-floor(step1))>1e-8))return 0;
}
if(b==0){
if(Y==0){
double tmp=X/(double)(a);
if(tmp>0&&(fabs(tmp-floor(tmp))<1e-8)){
step1=tmp;
int tmpx=0,tmpy=0;
for(int i=1;i<=step1;++i){
tmpx+=a;tmpy+=b;
if(dict.find(pair<int,int>(tmpx,tmpy))!=dict.end())return 0;
}
return 1;
}else return 0;
}else return 0;
}else{
step2=Y/(double)(b);
if(step2<=0||(fabs(step2-floor(step2))>1e-8))return 0;
}
if(step1==step2){
//blabla
int tmpx=0,tmpy=0;
for(int i=1;i<=step1;++i){
tmpx+=a;tmpy+=b;
if(dict.find(pair<int,int>(tmpx,tmpy))!=dict.end())return 0;
}
return 1;
}
else{
return 0;
}
}
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int F[600],FF[600][600];
int seq[100],cnt=0;
int BASE=250000;
int q[500005];
bool dfn[500005];
bool block[500005];
bool legal(int x){
return x>=0&&x<500005;
}
int sum1[500005],sum2[500005];
int cir[500005],T;
bool dfn2[500005];
int fff[500005];
int check3(int a,int b,int to){
b=-b;
memset(cir,0,sizeof(cir));
memset(dfn,0,sizeof(dfn));
memset(block,0,sizeof(block));
memset(sum1,0,sizeof(sum1));memset(sum2,0,sizeof(sum2));
for(int i=1;i<=cnt;++i)block[seq[i]+BASE]=true;
for(int i=1;i<500005;++i){
if(i>=a){
sum1[i]=sum1[i-a]+(block[i]);
}
else{
sum1[i]=(block[i]);
}
if(i>=b){
sum2[i]=sum2[i-b]+(block[i]);
}else{
sum2[i]=(block[i]);
}
}
++T;
for(int i=a*b+a+b;i<500005;++i){
if(sum1[i]-sum1[i-a*b-a]==0&&sum2[i]-sum2[i-a*b-b]==0)cir[i]=true;
}
int head=0,tail=0;dfn[BASE]=true;
q[tail++]=BASE;
while(head!=tail){
int x=q[head++];
if(legal(x+a)&&!dfn[x+a]&&!block[x+a]){
dfn[x+a]=true;q[tail++]=x+a;
}
if(legal(x-b)&&!dfn[x-b]&&!block[x-b]){
dfn[x-b]=true;q[tail++]=x-b;
}
}
if(!dfn[BASE+to])return 0;
memset(dfn2,0,sizeof(dfn2));
head=tail=0;dfn2[BASE+to]=true;
q[tail++]=BASE+to;
while(head!=tail){
int x=q[head++];
if(legal(x-a)&&!dfn2[x-a]&&!block[x-a]){
dfn2[x-a]=true;q[tail++]=x-a;
}
if(legal(x+b)&&!dfn2[x+b]&&!block[x+b]){
dfn2[x+b]=true;q[tail++]=x+b;
}
}
for(int i=0;i<500005;++i){
if(cir[i]&&dfn[i]&&dfn2[i]){
return -1;
}
}memset(dfn,0,sizeof(dfn));
memset(fff,0,sizeof(fff));fff[BASE]=1;
head=0,tail=0;dfn[BASE]=true;
q[tail++]=BASE;
while(head!=tail){
int x=q[head++];
if(legal(x+a)&&!dfn[x+a]&&!block[x+a]){
fff[x+a]=(fff[x+a]+fff[x])%mod;
dfn[x+a]=true;q[tail++]=x+a;
}
if(legal(x-b)&&!dfn[x-b]&&!block[x-b]){
fff[x-b]=(fff[x-b]+fff[x])%mod;
dfn[x-b]=true;q[tail++]=x-b;
}
}
return fff[BASE+to];
}
int check2(){//方向相同,可以同向,也可以反向
if(ax==0){
if(X!=0)return 0;
if((ay>0)==(by>0)){
//同向
int gy=gcd(ay,by);
memset(F,0,sizeof(F));
if(Y%gy!=0||Y/gy<0)return 0;
int A=ay/gy,B=by/gy;
F[0]=1;
for(int i=0;i<=Y/gy;++i){
if(dict.find(pair<int,int>(0,gy*i))!=dict.end())F[i]=0;
F[i+A]=(F[i+A]+F[i])%mod;F[i+B]=(F[i+B]+F[i])%mod;
}
return F[Y/gy];
}else{
//反向
int gy=gcd(fabs(ay),fabs(by));
if(Y%gy!=0)return 0;
cnt=0;
for(int i=1;i<=K;++i){
if(xx[i]==0&&yy[i]%gy==0){
seq[++cnt]=yy[i]/gy;
}
}
int A=ay/gy,B=by/gy;
if(A>0)return check3(A,B,Y/gy);
else return check3(B,A,Y/gy);
}
}else if(ay==0){
if(Y!=0)return 0;
if((ax>0)==(bx>0)){
//同向
int gx=gcd(ax,bx);
memset(F,0,sizeof(F));
if(X%gx!=0||X/gx<0)return 0;
int A=ax/gx,B=bx/gx;
F[0]=1;
for(int i=0;i<=X/gx;++i){
if(dict.find(pair<int,int>(gx*i,0))!=dict.end()){
F[i]=0;
}
F[i+A]=(F[i+A]+F[i])%mod;F[i+B]=(F[i+B]+F[i])%mod;
}
return F[X/gx];
}else{
//反向
int gx=gcd(fabs(ax),fabs(bx));
if(X%gx!=0)return 0;
cnt=0;
for(int i=1;i<=K;++i){
if(yy[i]==0&&xx[i]%gx==0){
seq[++cnt]=xx[i]/gx;
}
}
int A=ax/gx,B=bx/gx;
if(A>0)return check3(A,B,X/gx);
else return check3(B,A,X/gx);
}
}else{
if((ax>0)==(bx>0)){
//同向
int gx=gcd(ax,bx),gy=gcd(ay,by);
if(X%gx!=0||X/gx<0)return 0;
if(Y%gy!=0||Y/gy<0)return 0;
if(X/gx!=Y/gy)return 0;
int A=ax/gx,B=bx/gx;
memset(F,0,sizeof(F));
F[0]=1;
F[0]=1;
for(int i=0;i<=X/gx;++i){
if(dict.find(pair<int,int>(gx*i,gy*i))!=dict.end()){
F[i]=0;
}
F[i+A]=(F[i+A]+F[i])%mod;F[i+B]=(F[i+B]+F[i])%mod;
}
return F[X/gx];
}else{
//反向
int gx=gcd(fabs(ax),fabs(bx)),gy=gcd(fabs(ay),fabs(by));
if(X%gx!=0)return 0;
if(Y%gy!=0)return 0;
if(X/gx!=Y/gy)return 0;
cnt=0;
int A=ax/gx,B=bx/gx;
for(int i=1;i<=K;++i){
if(yy[i]%gy==0&&xx[i]%gx==0&&yy[i]/gy==xx[i]/gx){
seq[++cnt]=xx[i]/gx;
}
}
if(A>0)return check3(A,B,X/gx);
else return check3(B,A,X/gx);
}
}
//同向:一定无环,递推一波即可 //反向:可能有环... }
int fac[500005],inv[500005];
void init(){
fac[0]=1;
for(int i=1;i<500005;++i)fac[i]=fac[i-1]*1ll*i%mod;
inv[0]=1;
inv[1]=1;
for(int i=2;i<500005;++i)inv[i]=inv[mod%i]*1ll*(mod-mod/i)%mod;
for(int i=2;i<500005;++i){
inv[i]=inv[i-1]*1ll*inv[i]%mod;
}
}
int C(int n,int m){
return fac[n]*1ll*inv[m]%mod*inv[n-m]%mod;
}
int calc(int i,int j){
int dlt1=xx[j]-xx[i],dlt2=yy[j]-yy[i];
//double step1=,step2=;
double step2=(dlt1*1.0*ay-dlt2*1.0*ax)/(bx*1.0*ay-by*1.0*ax);
double step1=(dlt1*1.0*ay-step2*bx*ay)/ax/ay;
//必然有解.无解状况已经排除.
if(step1<0||step2<0)return 0;
if(fabs(step1-floor(step1))>1e-8||fabs(step2-floor(step2))>1e-8)return 0;
int n=step1,m=step2;
return C(n+m,m);
}
int f[20][2];bool vis[20];
int g[20][20],deg[20];
int main(){
freopen("knightmov.in","r",stdin);
freopen("knightmov.out","w",stdout);
int tests;scanf("%d",&tests);
init();
while(tests--){
scanf("%d%d%d",&X,&Y,&K);
scanf("%d%d%d%d",&ax,&ay,&bx,&by);
for(int i=1;i<=K;++i)scanf("%d%d",xx+i,yy+i);
if(ax==0&&ay==0&&bx==0&&by==0){
if(X==0&Y==0){
printf("-1\n");
}else{
printf("0\n");
}
continue;
}
dict.clear();
for(int i=1;i<=K;++i)dict.insert(pair<int,int>(xx[i],yy[i]));
if(ax==bx&&ay==by){
printf("%d\n",check4(ax,ay));
}
else if(ax==0&&ay==0){
printf("%d\n",check1(bx,by));
}else if(bx==0&&by==0){
printf("%d\n",check1(ax,ay));
}else{
double d1=direc(ax,ay),d2=direc(bx,by);
if(d1==d2){
printf("%d\n",check2());
}else{
if(X==0&&Y==0){
printf("1\n");continue;
}else{
memset(f,0,sizeof(f));
xx[0]=0;yy[0]=0;xx[K+1]=X;yy[K+1]=Y;
f[0][0]=1;
for(int i=1;i<=K+1;++i)vis[i]=false;vis[0]=false;
memset(g,0,sizeof(g));memset(deg,0,sizeof(deg));
for(int i=0;i<=K+1;++i){
for(int j=0;j<=K+1;++j){
if(i!=j){
g[i][j]=calc(i,j);
if(g[i][j])deg[j]++;
}
}
}
for(int i=0;i<=K+1;++i){
int x=0x7f7f7f7f;
for(int j=0;j<=K+1;++j){
if(deg[j]==0&&!vis[j]){
x=j;break;
}
}
if(x==0x7f7f7f7f)break;
vis[x]=true;
for(int t=0;t<=K+1;++t){
if(g[x][t]){
deg[t]--;
f[t][1]=(f[t][1]+f[x][0]*1ll*g[x][t]%mod)%mod;
f[t][0]=(f[t][0]+f[x][1]*1ll*g[x][t]%mod)%mod;
}
}
}
printf("%d\n",(f[K+1][1]-f[K+1][0]+mod)%mod);
}
}
}
}
// fclose(stdin);fclose(stdout);
return 0;
}
/*
3
3 3 0
1 2 2 1
9 9 2
1 2 2 1
1 2 6 6
1 1 0
0 0 0 0 */

CodeChef KnightMov的更多相关文章

  1. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1288  Solved: 490 ...

  2. 【BZOJ4260】 Codechef REBXOR 可持久化Trie

    看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...

  3. codechef 两题

    前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM, ...

  4. codechef January Challenge 2014 Sereja and Graph

    题目链接:http://www.codechef.com/JAN14/problems/SEAGRP [题意] 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1. [分析] 从结 ...

  5. BZOJ3509: [CodeChef] COUNTARI

    3509: [CodeChef] COUNTARI Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 85[Submit][St ...

  6. CodeChef CBAL

    题面: https://www.codechef.com/problems/CBAL 题解: 可以发现,我们关心的仅仅是每个字符出现次数的奇偶性,而且字符集大小仅有 26, 所以我们状态压缩,记 a[ ...

  7. CodeChef FNCS

    题面:https://www.codechef.com/problems/FNCS 题解: 我们考虑对 n 个函数进行分块,设块的大小为S. 每个块内我们维护当前其所有函数值的和,以及数组中每个元素对 ...

  8. codechef Prime Distance On Tree(树分治+FFT)

    题目链接:http://www.codechef.com/problems/PRIMEDST/ 题意:给出一棵树,边长度都是1.每次任意取出两个点(u,v),他们之间的长度为素数的概率为多大? 树分治 ...

  9. BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )

    树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...

随机推荐

  1. 微服务(SOP)日志管理

    问题: 大型企业应用规模大,调试 / 解决问题由于在生产环境中不会有开发环境的调试工具,如果需要模拟还原当时的环境, 目前的解决办法是进行日志记录 日志记录的常用方式: 使用SpringAop进行切入 ...

  2. POJ1035_Spell checker_KEY

    题目传送门 一道暴力可以过的水题.(直接暴力模拟的那种) 但是我打Trie练练模板,但是TMD因为数组开太小卡了好久. code: #include <cstdio> #include & ...

  3. python 多线程笔记(2)-- 锁

    锁是什么?什么场合使用锁? 锁是一种机制,用于保护那些会引起冲突的资源. 比如上厕所,进去之后第一件事干嘛?把厕所门反锁!表示什么呢?表示这个厕所正在使用中! 至于在厕所里面干大事.干小事.还是打飞机 ...

  4. 【CF995F】Cowmpany Cowmpensation

    [CF995F]Cowmpany Cowmpensation 题面 树形结构,\(n\)个点,给每个节点分配工资\([1,d]\),子节点不能超过父亲节点的工资,问有多少种分配方案 其中\(n\leq ...

  5. 洛谷P1514 引水入城

    洛谷P1514 引水入城 原题链接 一道好题...细节真多 第一次提交90分,然后就GG了,不知从何改起 其实比较简单吧... 首先,一个点的水流向最后一排,一定可以形成一个区间. 不行的话肯定GG ...

  6. Unity编辑器扩展chapter1

    Unity编辑器扩展chapter1 unity通过提供EditorScript API 的方式为我们提供了方便强大的编辑器扩展途径.学好这一部分可以使我们学会编写一些工具来提高效率,甚至可以自制一些 ...

  7. [network]交换机中用户权限

    LEVEL 0(访问级):可以执行用于网络诊断等功能的命令.包括ping.tracert.telnet等命令,执行该级别命令的结果不能被保存到配置文件中. LEVEL 1(监控级):可以执行用于系统维 ...

  8. JavaScript学习笔记(一)——JS速览

    第一章 JS速览 1 限制时间处理事件 <script> setTomeout(wakeUpUser,5000); function wakeUpUser() { alert(" ...

  9. ConcurrentHashMap(JDK1.8)为什么要放弃Segment

    今天看到一篇博客:jdk1.8的HashMap和ConcurrentHashMap,我想起了前段时间面试的一个问题:ConcurrentHashMap(JDK1.8)为什么要使用synchronize ...

  10. Machine Learning方法总结

    Kmeans——不断松弛(?我的理解)模拟,将点集分成几堆的算法(堆数需要自己定). 局部加权回归(LWR)——非参数学习算法,不用担心自变量幂次选择.(因此当二次欠拟合, 三次过拟合的时候不妨尝试这 ...