HDU 5794 A Simple Chess

可以用总方案数减去经过障碍物的方案数。

先写一个判断某点是否可达的函数~ check(a,b)

再写一个某点到某点的方案数的函数~ cal(x1,x2,y1,y2)

设随便走 从(1,1)到(n,m)的方案数为P

设从(1,1)走到第i个障碍物并且不经过其余障碍物的方案数为num[i]。

那么 answer = P - sum{ num[i] * cal(x[i],y[i],n,m) }。

计算num[i] 可以将所有的障碍物按照x从小到大排个序,然后o(r*r)效率得到。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-8;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
inline int read()
{
    char c = getchar();  while(!isdigit(c)) c = getchar();
    int x = 0;
    while(isdigit(c)) { x = x * 10 + c - ‘0‘; c = getchar(); }
    return x;
}

LL mod=110119;

LL PowMod(LL a,LL b,LL MOD){
    LL ret=1;
    while(b){ if(b&1) ret=(ret*a)%MOD; a=(a*a)%MOD; b>>=1; }
    return ret;
}
LL fac[120000];

LL Lucas(LL n,LL m,LL p)
{
    LL ret=1;
    while(n&&m)
    {
        LL a=n%p,b=m%p;
        if(a<b) return 0;
        ret=(ret*fac[a]*PowMod(fac[b]*fac[a-b]%p,p-2,p))%p;
        n/=p, m/=p;
    }
    return ret;
}

bool check(LL a,LL b)
{
    if((a+b+1)%3!=0) return 0;
    LL f=(a+b+1)/3; f--;
    LL aa=a-f,bb=b-f;
    if(aa<=0||bb<=0) return 0;
    return 1;
}

LL cal(LL A,LL B,LL a,LL b)
{
    if(!check(a,b)) return 0;
    if(!check(A,B)) return 0;
    LL f,na,nb,nA,nB;
    f=(A+B+1)/3; f--; nA=A-f,nB=B-f;
    f=(a+b+1)/3; f--; na=a-f,nb=b-f;
    if(na-nA<0||nb-nB<0) return 0;
    return Lucas(nb-nB+na-nA,na-nA,mod);
}

LL N,M,r,num[110];
struct X { LL x,y; }s[110];
bool cmp(X a,X b){return a.x<b.x;}

int main()
{
    int cas=1;
    fac[0]=1; for(int i=1;i<=(int)mod;i++) fac[i]=(fac[i-1]*i)%mod;
    while(~scanf("%lld%lld%d",&N,&M,&r))
    {
        for(int i=1;i<=r;i++) scanf("%lld%lld",&s[i].x,&s[i].y);
        sort(s+1,s+1+r,cmp);
        printf("Case #%d: ",cas++);
        if(!check(N,M)) printf("0\n");
        else
        {
            LL ans=cal(1,1,N,M);
            for(int i=1;i<=r;i++)
            {
                num[i]=cal(1,1,s[i].x,s[i].y);
                for(int j=1;j<i;j++)
                    num[i]=(num[i]-num[j]*cal(s[j].x,s[j].y,s[i].x,s[i].y)%mod+mod)%mod;
            }
            for(int i=1;i<=r;i++) ans=(ans-num[i]*cal(s[i].x,s[i].y,N,M)%mod+mod)%mod;
            printf("%lld\n",ans);
        }
    }
    return 0;
}
时间: 2024-08-06 11:51:16

HDU 5794 A Simple Chess的相关文章

HDU 5794 A Simple Chess(杨辉三角+容斥原理+Lucas)

题目链接 A Simple Chess 打表发现这其实是一个杨辉三角…… 然后发现很多格子上方案数都是0 对于那写可能可以到达的点(先不考虑障碍点),我们先叫做有效的点 对于那些障碍,如果不在有效点上,则自动忽略 障碍$(A, B)$如果有效,那么就要进行如下操作: 以这个点为一个新的杨辉三角的顶点,算出目标点的坐标$(x, y)$. 目标点的答案减去$C(A, B) * C(x, y)$的值. 但是这样会造成重复计算,原因是障碍之间可能有相互影响的关系. 这个时候就要考虑容斥原理,DFS消除这

HDU 5794 A Simple Chess(卢卡斯定理 + 容斥原理)

传送门 A Simple Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 667    Accepted Submission(s): 168 Problem Description There is a n×m board, a chess want to go to the position (n,m) from the

HDU 5794 A Simple Chess (Lucas + dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5794 多校这题转化一下模型跟cf560E基本一样,可以先做cf上的这个题. 题目让你求一个棋子开始在(1,1),只能像马一样走且往右下方走,不经过坏点,有多少种走法能到达(n,m)点. 比如n=6, m=5 有两个坏点,模型转换 如下图: 转换成简单模型之后,只要把棋子可能经过的坏点存到结构体中,按照x与y从小到大排序. dp[i]表示从起点到第i个坏点且不经过其他坏点的方案数. dp[i] = L

HDU 5794 A Simple Nim 2016多校第六场1003

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5795 题意:给你n堆石子,每一堆有ai石头,每次有两种操作,第一种在任意一堆取出任意数量的石头但不能为0,第二种把一堆石头分成三堆任意数量的石头(不能为0),问是先手赢还是后手赢. 题解:这就是一个Nim游戏!那么Nim游戏一般跟SG函数有关,所以这道题打表找规律即可. 关于SG函数,在这里也说一下吧!毕竟第一次接触. Nim游戏与SG函数:http://baike.baidu.com/link?u

HDU 5794 - A Simple Nim

题意:    n堆石子,先拿光就赢,操作分为两种:        1.任意一堆中拿走任意颗石子        2.将任意一堆分成三小堆 ( 每堆至少一颗 )        分析:    答案为每一堆的SG函数值异或和.    故先打表寻找单堆SG函数规律.    其中,若 x 可分为 三堆 a,b,c ,则 SG[x] 可转移至子状态 SG[a] ^ SG[b] ^ SG[c]  (三堆SG值异或和)        打表后发现:        SG[ 8*k - 1 ] = 8*k       

hdu5794 A Simple Chess 容斥+Lucas 从(1,1)开始出发,每一步从(x1,y1)到达(x2,y2)满足(x2?x1)^2+(y2?y1)^2=5, x2&gt;x1,y2&gt;y1; 其实就是走日字。而且是往(n,m)方向走的日字。还有r个障碍物,障碍物不可以到达。求(1,1)到(n,m)的路径条数。

A Simple Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2597    Accepted Submission(s): 691 Problem Description There is a n×m board, a chess want to go to the position (n,m) from the pos

hdu 4974 A simple water problem(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4974 Problem Description Dragon is watching competitions on TV. Every competition is held between two competitors, and surely Dragon's favorite. After each competition he will give a score of either 0 or

hdu 4975 A simple Gaussian elimination problem.(网络流,判断矩阵是否存在)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4975 Problem Description Dragon is studying math. One day, he drew a table with several rows and columns, randomly wrote numbers on each elements of the table. Then he counted the sum of each row and col

hdu 4267 A Simple Problem with Integers

题目链接:hdu 4267 A Simple Problem with Integers 类似于题目:hdu 1556 Color the ball 的技巧实现树状数组的段更新点查询. 由于该题对于段的更新并不是连续的,从而可以构造多个树状数组.因为$k \in [1,10] $,从而可以把更新划分为如下类型: 1,2,3,4,5... ------------- 1,3,5,7,9... 2,4,6,8,10... ------------- 1,4,7,10,13... 2,5,8,11,1