容斥定理 -- 第九屆ACM山東省賽F題 Four-tuples (SDUT4219)
阿新 • • 發佈:2018-12-24
Four-tuples
Time Limit: 2000 msMemory Limit: 524288 KiBOutput
For each test case, output one line containing one integer, representing the answer.
Sample Input
1 1 1 2 2 3 3 4 4
Sample Output
1
Hint
Source
2018 Shandong ACM programing real contest, on-site problem replay 解題報告:容斥原理第一種特殊情況 : x1 = x2 , 第二種特殊情況 : x2 = x3 ,結果 = 總情況 - 總特殊情況
注意!這裡jiao求的交集,並非容斥定理中的交集,現場時就是弄混了,然後就亂了
程式碼:#include<bits/stdc++.h> using namespace std; long long mo(long long x) { return x % ((long long)1e9 + 7); } long long jiao2(int l1, int r1, int l2, int r2) { long long ans = min(r1, r2) - max(l1, l2) + 1; if(ans <= 0) return 0; else return ans; } long long jiao3(int l1, int r1, int l2, int r2, int l3,int r3) { long long ans = min(r1, min(r2, r3)) - max(l1, max(l2, l3)) + 1; if(ans <= 0) return 0; else return ans; } long long jiao4(int l1, int r1, int l2, int r2, int l3,int r3, int l4, int r4) { long long ans = min(min(r1, r2), min(r3, r4)) - max(max(l1, l2), max(l3, l4)) + 1; if(ans <= 0) return 0; else return ans; } int main() { int l[8], r[8], t; long long sum; scanf("%d", &t); while(t--) { sum = 1; for(int i = 0; i < 4; i++) { scanf("%d%d", &l[i], &r[i]); l[i + 4] = l[i]; r[i + 4] = r[i]; sum *= (r[i] - l[i] + 1); sum %= (long long)1e9 + 7; } // A + B + C + D 即一交集 for(int i = 0; i < 4; i++) { sum -= mo(mo(jiao2(l[i], r[i], l[i + 1], r[i + 1]) * (r[i + 2] - l[i + 2] + 1)) * (r[i + 3] - l[i + 3] + 1)); while(sum < 0) sum += (long long)1e9 + 7; } // A U B 即二交集 for(int i = 0; i < 4; i++) { sum += jiao3(l[i], r[i], l[i + 1], r[i + 1], l[i + 2], r[i + 2]) * (r[i + 3] - l[i + 3] + 1); sum %= (long long)1e9 + 7; } //二交集中 A U C, B U D sum += jiao2(l[0], r[0], l[1], r[1]) * jiao2(l[2], r[2], l[3], r[3]); sum %= (long long)1e9 + 7; sum += jiao2(l[1], r[1], l[2], r[2]) * jiao2(l[0], r[0], l[3], r[3]); sum %= (long long)1e9 + 7; // A U B U C == A U B U C U D 即三交集與四交集 sum -= mo(3 * jiao4(l[0], r[0], l[1], r[1], l[2], r[2], l[3], r[3]) ); while(sum < 0) sum += (long long)1e9 + 7; printf("%lld\n", sum); //驗證部分 sum = 0; for(int i = l[0]; i <= r[0]; i++) for(int j = l[1]; j <= r[1]; j++) for(int k = l[2]; k <= r[2]; k++) for(int p = l[3]; p <= r[3]; p++) { if(i != j && j != k && k != p && p != i) { sum++; if(sum >= (1e9 + 7)) { cout << "暴力要掛了" <<endl; return 0; sum -= (1e9 + 7); } } } printf("暴力標準答案:%lld\n", sum); } return 0; }
最後, 我國超算的發展遠遠超越了美帝的想象,高手在民間。