HDU 4365 Palindrome graph(几何变换+快速幂)

来源:互联网 发布:red hat linux 6.0 编辑:程序博客网 时间:2024/05/22 02:15

HDU 4365

题意:给你一个n*n的画,然后每个格子图上任意k种颜色之一,要求通过翻转旋转后与原图保持一致,且原图已有m个格子有颜色。求有多少种涂法?

思路:

可以发现,我们所求的画是个高度轴对称和中心对称的图形,我们沿两根对称轴与两根中心对称轴把图案切成八份,那么决定其涂色方案只需考虑其中一份即可,若其中一份有x个格子那么答案即是k^x。

然而还有一个条件,即已经有m个格子涂上了颜色,那么我们将m个格子映射至之前选择的八分之一区域内,表明该格子颜色已固定,假设有y个格子颜色已固定,那么答案即是k^(x-y)。

求答案的过程中记得使用快速幂。。以及注意mod = 1e8+7,不是1e9+7..

code:

/** @author Novicer* language : C++/C*/#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>#define INF 2147483647#define cls(x) memset(x,0,sizeof(x))#define rise(i,a,b) for(int i = a ; i <= b ; i++)using namespace std;const double eps(1e-8);typedef long long lint;const int maxm = 10000 + 5;const lint mod = 1e8 + 7;lint n,m,k;map<lint , int> mp;lint ans;lint fast_pow(lint n , lint k){lint res = 1;while(k > 0){if(k&1) res = (res * n) % mod;k >>= 1;n = (n * n) % mod;}return res;}void change(int &x , int &y){while(1){if(x >= 0 && y >= 0 && x <= y && x <= n/2 && y <= n/2) break;if(x > n/2 && y > n/2){x = n - x + 1;y = n - y + 1;}if(x <= n/2 && y > n/2){y = n - y + 1;}if(x > n/2 && y <= n/2){x = n - x + 1;}if(x > y) swap(x,y);}}void solve(){mp.clear();if(n&1){ans = (n/2 + 2) * (n/2 + 1) / 2;}else ans = (n/2) * (n/2 + 1) / 2;for(int i = 1 ; i <= m ; i++){int x , y;scanf("%d%d",&x,&y);x++;y++;change(x,y);if(!mp[x + 10000*y]){mp[x + 10000*y] = 1;ans --;}}ans = fast_pow(k, ans) % mod;cout << ans <<  endl;}int main(){while(cin >> n >> m >> k){solve();}return 0;}


0 0
原创粉丝点击