2016多校训练Contest6: 1002 A Simple Chess hdu5794
2016-08-04 23:53
399 查看
Problem Description
There is a n×m board,
a chess want to go to the position
(n,m) from
the position (1,1).
The chess is able to go to position (x2,y2) from
the position (x1,y1),
only and if only x1,y1,x2,y2 is
satisfied that (x2−x1)2+(y2−y1)2=5, x2>x1, y2>y1.
Unfortunately, there are some obstacles on the board. And the chess never can stay on the grid where has a obstacle.
I want you to tell me, There are how may ways the chess can achieve its goal.
Input
The input consists of multiple test cases.
For each test case:
The first line is three integers, n,m,r,(1≤n,m≤1018,0≤r≤100),
denoting the height of the board, the weight of the board, and the number of the obstacles on the board.
Then follow r lines,
each lines have two integers, x,y(1≤x≤n,1≤y≤m),
denoting the position of the obstacles. please note there aren't never a obstacles at position (1,1).
Output
For each test case,output a single line "Case #x: y", where x is the case number, starting from 1. And y is the answer after module 110119.
Sample Input
Sample Output
似乎数据特别水。。只要把不可到达的点删掉然后2^k容斥就可以直接过了。。并不明白怎么造的数据
正常的做法的话。。
我们用f[i]维护到某个障碍前面不经过任何障碍的方案数
然后转移的时候算出1,1到i的次数,
枚举1到i-1所有的障碍,乘走过中间部分的方案数,把这些减去
最后r+1加入终点
ans就是f[r+1]
这样复杂度是r^2的。
1,1到x,y的方案数,我们考虑马的走法,可以换成先往右下走一格,然后往右或者往下走。
因为总步数一定,所以可以组合数求解
拖了个lucas模版
There is a n×m board,
a chess want to go to the position
(n,m) from
the position (1,1).
The chess is able to go to position (x2,y2) from
the position (x1,y1),
only and if only x1,y1,x2,y2 is
satisfied that (x2−x1)2+(y2−y1)2=5, x2>x1, y2>y1.
Unfortunately, there are some obstacles on the board. And the chess never can stay on the grid where has a obstacle.
I want you to tell me, There are how may ways the chess can achieve its goal.
Input
The input consists of multiple test cases.
For each test case:
The first line is three integers, n,m,r,(1≤n,m≤1018,0≤r≤100),
denoting the height of the board, the weight of the board, and the number of the obstacles on the board.
Then follow r lines,
each lines have two integers, x,y(1≤x≤n,1≤y≤m),
denoting the position of the obstacles. please note there aren't never a obstacles at position (1,1).
Output
For each test case,output a single line "Case #x: y", where x is the case number, starting from 1. And y is the answer after module 110119.
Sample Input
1 1 0 3 3 0 4 4 1 2 1 4 4 1 3 2 7 10 2 1 2 7 1
Sample Output
Case #1: 1 Case #2: 0 Case #3: 2 Case #4: 1 Case #5: 5
似乎数据特别水。。只要把不可到达的点删掉然后2^k容斥就可以直接过了。。并不明白怎么造的数据
正常的做法的话。。
我们用f[i]维护到某个障碍前面不经过任何障碍的方案数
然后转移的时候算出1,1到i的次数,
枚举1到i-1所有的障碍,乘走过中间部分的方案数,把这些减去
最后r+1加入终点
ans就是f[r+1]
这样复杂度是r^2的。
1,1到x,y的方案数,我们考虑马的走法,可以换成先往右下走一格,然后往右或者往下走。
因为总步数一定,所以可以组合数求解
拖了个lucas模版
#include<map> #include<cmath> #include<queue> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct obstacles { long long x,y; bool operator <(obstacles z) const { return x<z.x||x==z.x&&y<z.y; } }a[1001]; long long f[1001]; long long mod=110119; long long p1[1000001],p2[1000001]; inline long long PowMod(long long a,long long b) { long long ret=1; while(b) { if(b&1) ret=(ret*a)%mod; a=(a*a)%mod; b>>=1; } return ret; } long long fac[1000005]; inline long long Get_Fact(long long p) { fac[0]=1; for(int i=1;i<=p;i++) fac[i]=(fac[i-1]*i)%p; } inline long long Lucas(long long n,long long m,long long p) { long long ret=1; while(n&&m) { long long a=n%mod,b=m%mod; if(a<b) return 0; ret=(ret*fac[a]*PowMod(fac[b]*fac[a-b]%p,p-2))%p; n/=p; m/=p; } return ret; } inline long long cale(int i,int j) { long long n=a[j].x-a[i].x,m=a[j].y-a[i].y; if((m+n)%(long long)3!=0) return 0; long long step=(m+n)/(long long)3; n-=step; m-=step; if(n<0||m<0) return 0; return Lucas(n+m,m,mod); } inline bool check(int i,int j) { if(a[i].x>a[j].x||a[i].y>a[j].y) return false; return true; } int main() { Get_Fact(mod); int k=0; long long n,m; int r; while(scanf("%I64d%I64d%d",&n,&m,&r)!=EOF) { k++; int i,j; for(i=1;i<=r;i++) scanf("%I64d%I64d",&a[i].x,&a[i].y); r++; a[i].x=n; a[i].y=m; sort(a+1,a+1+r); a[0].x=1; a[0].y=1; f[0]=1; for(i=1;i<=r;i++) { f[i]=cale(0,i); for(j=1;j<=i-1;j++) { if(check(j,i)) f[i]-=f[j]*cale(j,i)%mod; while(f[i]<0) f[i]+=mod; } } printf("Case #%d: %I64d\n",k,f[r]); } return 0; }
相关文章推荐
- 2016多校训练Contest10: 1002 Hard problem hdu5858
- 2016多校训练#1 1002 组合博弈
- 2016多校训练Contest9: 1002 Best Division hdu5845
- 2016多校训练Contest6: 1010 Windows 10 hdu5802
- 2016多校训练Contest6: 1007 This world need more Zhu hdu5799
- HDU 5858 Hard problem (2016 多校训练#10 1002)
- 2016多校训练Contest6: 1008 To My Girlfriend hdu5800
- 2016多校训练Contest6: 1001 A Boring Question hdu5793
- 2016多校联合训练contest4 1012Bubble Sort
- 2016多校训练Contest4: 1010 The All-purpose Zero hdu5773
- 2016多校训练Contest5: 1003 Divide the Sequence hdu5783
- 2016多校训练Contest5: 1011 Two hdu5791
- 2016多校训练#5 1012 HDU 5792 树状数组 代码详解
- 2016多校训练Contest7: 1008 Hearthstone hdu5816
- 2016第三场多校联盟训练1003
- HDOJ 5792 (2016多校联合训练 Training Contest 5) World is Exploding
- 2016多校训练Contest8: 1008 Rikka with Sequence hdu5828
- HDOJ 5738 (2016多校联合训练 Training Contest 2) Eureka
- 2016第三场多校联盟训练1010
- [HDU5741] Helter Skelter [2016 Multi-University Training Contest 2(2016多校联合训练2) H]