D题
并查集+组合
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define MOD 1000000007 int o[2001]; int find(int x) { int t,r; t = x; while(x != o[x]) x = o[x]; while(x != t) { r = o[t]; o[t] = x; t = r; } return x; } void merge(int x,int y) { x = find(x); y = find(y); if(x != y) o[x] = y; } int main() { int i,j,n,m,k,ans = 0; scanf("%d%d%d",&n,&m,&k); for(i = 1;i <= n;i ++) o[i] = i; for(i = 1;i <= n;i ++) { if(k%2 == 0) { if(2*i < k) continue; if(i + k/2 > n) continue; for(j = 0;j < k/2;j ++) { merge(i-j,i+1+j); } } else { if(2*i-1 < k) continue; if(i + k/2 > n) continue; for(j = 0;j < k/2;j ++) merge(i-1-j,i+1+j); } } for(i = 1;i <= n;i ++) { if(find(i) == i) ans ++; } int sd = 1; for(i = 1;i <= ans;i ++) sd = ((__int64)sd*m)%MOD; printf("%d ",sd); return 0; }