Codeforces 809C [数位DP]
2017-05-25 20:41
225 查看
DescriptionDescription
这个题好像就是求∑x1≤i≤x2,y1≤j≤y2[ai,j≤k]∗ai,j∑x1≤i≤x2,y1≤j≤y2[ai,j≤k]∗ai,j
其中
ai,j=(i−1)xor(j−1)+1ai,j=(i−1)xor(j−1)+1
那么就可以搞成两个东西
∑i∑j[i∑i∑j[i xorxor j≤k]+∑i∑j[ij≤k]+∑i∑j[i xorxor j≤k]∗(ij≤k]∗(i xorxor j)j)
好像数位DP搞一搞就好了。。。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int MOD = 1000000007; inline char get(void) { static char buf[100000], *S = buf, *T = buf; if (S == T) { T = (S = buf) + fread(buf, 1, 100000, stdin); if (S == T) return EOF; } return *S++; } inline void read(int &x) { static char c; x = 0; for (c = get(); c < '0' || c > '9'; c = get()); for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0'; } int test, x1, x2, y1, y2, k, ans; int dp1[40][2][2][2], dp2[40][2][2][2]; int A[40], B[40], C[40]; inline void add(int &x, int y) { x += y; while (x >= MOD) x -= MOD; } inline void dda(int &x, int y) { x -= y; while (x < 0) x += MOD; } int Calc(int X, int Y, int k) { if (X < 0 || Y < 0 || k < 0) return 0; memset(dp1, 0, sizeof dp1); memset(dp2, 0, sizeof dp2); // dp1维护第一个式子,dp2维护第二个式子 for (int i = 0; i < 31; i++) { A[i] = X & 1; X >>= 1; B[i] = Y & 1; Y >>= 1; C[i] = k & 1; k >>= 1; } reverse(A, A + 31); reverse(B, B + 31); reverse(C, C + 31); dp1[0][1][1][1] = 1; for (int i = 0; i < 31; i++) for (int a = 0; a < 2; a++) for (int b = 0; b < 2; b++) for (int c = 0; c < 2; c++) for (int x = 0; x < 2; x++) for (int y = 0; y < 2; y++) { int z = x ^ y; if (a == 1 && x == 1 && A[i] == 0) continue; if (b == 1 && y == 1 && B[i] == 0) continue; if (c == 1 && z == 1 && C[i] == 0) continue;// 判断DP到的是否在询问内 add(dp1[i + 1][a & (A[i] == x)][b & (B[i] == y)][c & (C[i] == z)], dp1[i][a][b][c]); add(dp2[i + 1][a & (A[i] == x)][b & (B[i] == y)][c & (C[i] == z)], dp2[i][a][b][c]); add(dp2[i + 1][a & (A[i] == x)][b & (B[i] == y)][c & (C[i] == z)], (ll)dp1[i][a][b][c] * (z << (30 - i)) % MOD); } int sum = 0; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) for (int k = 0; k < 2; k++) { add(sum, dp1[31][i][j][k]); add(sum, dp2[31][i][j][k]); } return sum; } int main(void) { read(test); while (test--) { read(x1); read(y1); read(x2); read(y2); read(k); ans = 0; x1--; y1--; x2--; y2--; k--; add(ans, Calc(x2, y2, k)); add(ans, Calc(x1 - 1, y1 - 1, k)); dda(ans, Calc(x2, y1 - 1, k)); dda(ans, Calc(x1 - 1, y2, k)); printf("%d\n", ans); } return 0; }
相关文章推荐
- Codeforces 55D Beautiful numbers【数位dp】
- Codeforces 55D Beautiful numbers --- 数位DP
- codeforces 55D Beautiful numbers[数位dp]
- codeforces 55D. Beautiful numbers 数位dp
- Codeforces 628D. Magic Numbers 数位DP
- Codeforces 55D Beautiful numbers 数位dp 数论 优化技巧
- CodeForces 55D A - Beautiful numbers(数位dp)(模板)
- codeforces 55D Beautiful numbers Codeforces Beta Round #51(数位dp)
- codeforces 55D. Beautiful numbers(数位dp)
- CodeForces 215E Periodical Numbers 数位DP
- Codeforces 55D. Beautiful numbers (数位DP)
- Codeforces-55D - Beautiful numbers - 数位DP
- CodeForces - 258B King's Path(数位dp)
- Codeforces 55D Beautiful numbers 数位DP
- [数位dp] Codeforces 401D Roman and Numbers
- 【数位dp && 优化数组范围】CodeForces - 55D Beautiful numbers
- Codeforces 204A Little Elephant and Interval(数位DP)
- CodeForces 55D Beautiful numbers (数位DP)
- codeforces 55D Beautiful numbers(数位DP)
- codeforces 9C 数位DP做法