/*发现算来算去所有数的二进制1的个数和位置不会变。两个数and 或 or只是把他们的二进制位的1聚拢到一个数上。若两个数为a,b,假设他们进行一次操作后变为(a+x),(b-x),则a>b那么(a+x)^2+(b-x)^2=a^2+b^2+2x(x+a-b)>a^2+b^2说明这种“聚拢”操作后平方和会变大所以把所有数的二进制位1统计下来后尽可能的对分给一个数即可。*/#include#define mod 998244353#define N 10005using namespace std;int n,x;int cnt[N];int main(){ freopen("s.in","r",stdin); freopen("s.out","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&x); for (int j=0;j<32;j++) if (x & (1<
#include#define N 30#define ll long long#define mod 1000000007#define opt 99999using namespace std;int n,m,k,lim;ll ans;int dx[4]={ 0,0,1,-1};int dy[4]={ 1,-1,0,0};int vis[N][N],f[N][N];inline ll read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){ if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}bool can(int x,int y){ if(vis[x][y]==-1) return false; for(int i=max(1,y-2);i<=min(y+2,m);i++) if(vis[x][i]>=opt) return false; for(int i=max(1,x-2);i<=min(n,x+2);i++) if(vis[i][y]>=opt) return false; if(vis[x-1][y-1]>=opt || vis[x-1][y+1]>=opt) return false; if(vis[x+1][y+1]>=opt || vis[x+1][y-1]>=opt) return false; return true;}void update(int x,int y){ vis[x][y]=opt; for(int i=max(1,y-2);i<=min(y+2,m);i++) if(vis[x][i]!=-1)vis[x][i]++; for(int i=max(1,x-2);i<=min(n,x+2);i++) if(vis[i][y]!=-1)vis[i][y]++; if(x-1 && y-1 && vis[x-1][y-1]!=-1) vis[x-1][y-1]++; if(x-1 && y+1<=m && vis[x-1][y+1]!=-1) vis[x-1][y+1]++; if(x+1<=n && y-1 && vis[x+1][y-1]!=-1) vis[x+1][y-1]++; if(x+1<=n && y+1<=m && vis[x+1][y+1]!=-1) vis[x+1][y+1]++;}void _update(int x,int y){ vis[x][y]=0; for(int i=max(1,y-2);i<=min(y+2,m);i++) if(vis[x][i]>0)vis[x][i]--; for(int i=max(1,x-2);i<=min(n,x+2);i++) if(vis[i][y]>0)vis[i][y]--; if(vis[x-1][y-1]>0)vis[x-1][y-1]--; if(vis[x-1][y+1]>0)vis[x-1][y+1]--; if(vis[x+1][y-1]>0)vis[x+1][y-1]--; if(vis[x+1][y+1]>0)vis[x+1][y+1]--; f[x][y]=0;}void dfs(int x,int y,int L){ if(L==0) { ans++;ans%=mod; return; } for(int xx=x;xx<=n;xx++) for(int yy=1;yy<=m;yy++) { if(f[xx][yy]) continue; if(vis[xx][yy]
#include#include #include const int MAXN = 15;const int MOD = 1e9 + 7;int m;inline unsigned int getBit(int i) { return 1u << i;}inline bool isValidLine(unsigned int s) { return !((s & (s << 1)) || (s & (s << 2)));}inline bool isValidTwoLines(unsigned int a, unsigned int b) { return !((a & (b << 1)) || (a & (b >> 1)) || (a & b)); }inline bool isValidThreeLines(unsigned int a, unsigned int b, unsigned int c) { return !(a & c) && isValidTwoLines(a, b)/* && isValidTwoLines(b, c)*/;}int main() { freopen("l.in", "r", stdin); freopen("l.out", "w", stdout); int n, k; scanf("%d %d %d", &n, &m, &k); unsigned int ban[n + 1]; memset(ban, 0, sizeof(ban)); while (k--) { int i, j; scanf("%d %d", &i, &j); ban[i] |= 1 << (j - 1); } std::vector validStates; unsigned int maxS = 1 << m; for (int i = 0; i < maxS; i++) { if (isValidLine(i)) { validStates.push_back(i); } } // f[i][state of line i - 1][state of line i] = count long long f[n + 1][validStates.size()][validStates.size()]; memset(f, 0, sizeof(f)); for (int a = 0; a < (int)validStates.size(); a++) f[0][0][a] = 1; long long ans = 0; for (int i = 1; i <= n; i++) { for (int c = 0; c < (int)validStates.size(); c++) { if (ban[i] & validStates[c]) continue; for (int b = 0; b < (i <= 1 ? 1 : (int)validStates.size()); b++) { if (!isValidTwoLines(validStates[b], validStates[c])) continue; if (ban[i - 1] & validStates[b]) continue; for (int a = 0; a < (i <= 2 ? 1 : (int)validStates.size()); a++) { if (!isValidThreeLines(validStates[a], validStates[b], validStates[c])) continue; if (a && (ban[i - 2] & validStates[a])) continue; (f[i][b][c] += f[i - 1][a][b]) %= MOD; } if (i == n) (ans += f[i][b][c]) %= MOD; } } } printf("%lld\n", ans);}
暂时放弃 先做完互不侵犯king再来写这道题