Problem Description
Given l1,r1,l2,r2,l3,r3,l4,r4l_1,r_1,l_2,r_2,l_3,r_3,l_4,r_4l1,r1,l2,r2,l3,r3,l4,r4, please count the number of four-tuples (x1,x2,x3,x4)(x_1,x_2,x_3,x_4)(x1,x2,x3,x4) such that li≤xi≤ril_i\le x_i\le r_ili≤xi≤ri and x1≠x2,x2≠x3,x3≠x4,x4≠x1x_1\ne x_2,x_2\ne x_3,x_3\ne x_4,x_4\ne x_1x1≠x2,x2≠x3,x3≠x4,x4≠x1. The answer should modulo 109+710^9+7109+7 before output.
Input
The input consists of several test cases. The first line gives the number of test cases, T(1≤T≤106)T(1\le T\le 10^6)T(1≤T≤106).
For each test case, the input contains one line with 888 integers l1,r1,l2,r2,l3,r3,l4,r4(1≤li≤ri≤109)l_1,r_1,l_2, r_2, l_3,r_3,l_4,r_4(1\le l_i\le r_i\le 10^9)l1,r1,l2,r2,l3,r3,l4,r4(1≤li≤ri≤109).
Output
For each test case, output one line containing one integer, representing the answer.
这个F真的是十分扎心,一道能卡出银铜分布的题。感觉比赛时我们讨论了很多种方法,都是将问题复杂化了,最后交的代码虽然简化了些,但还是略微复杂,重判后果然错了。
容斥,自然是从最多的情况开始倒推重复的情况与少加的情况。
现在不少博客讲的都很明白,就贴一个点击打开链接。
自己再写也错了些小地方,还是对拍找的的错误。。。
#include <bits/stdc++.h> #define ms(x) memset(x, 0, sizeof(x)) #define ll long long using namespace std; const int N = 1123; const int mod = 1e9+7; struct node{ ll l, r; }; ll total(node a){ return (a.r - a.l + 1)%mod; } ll join2(node a, node b, node c, node d){ // a&b ll up = max(a.l, b.l); ll down = min(a.r, b.r); ll ans = ((down - up + 1)%mod * total(c))%mod; ans = (ans*total(d))%mod; if(ans<=0) return 0; else return ans%mod; } ll join3(node a, node b, node c, node d){ // a&b&c ll up = max(max(a.l, b.l),c.l); ll down = min(min(a.r,b.r),c.r); ll ans = ((down - up + 1)%mod * total(d))%mod; if(ans<=0) return 0; else return ans%mod; } ll join2and2(node a, node b, node c, node d){ // a&b && c&d ll up1 = max(a.l, b.l); ll down1 = min(a.r, b.r); ll up2 = max(c.l, d.l); ll down2 = min(c.r, d.r); if(down1-up1+1<=0) return 0; if(down2-up2+1<=0) return 0; ll ans = ((down1 - up1 + 1)%mod *(down2 - up2 + 1)%mod)%mod ; if(ans<=0) return 0; else return ans%mod; } ll join4(node a, node b, node c, node d){ ll up = max(max(max(a.l, b.l),c.l), d.l); ll down = min(min(min(a.r,b.r),c.r),d.r); ll ans = down - up + 1; if(ans<=0) return 0; else return ans%mod; } int main(){ int T; // freopen("in.txt","w",stdout); scanf("%d", &T); while(T--){ node a, b, c, d; scanf("%lld%lld%lld%lld%lld%lld%lld%lld", &a.l, &a.r, &b.l, &b.r, &c.l, &c.r, &d.l, &d.r); ll ans = (((total(a) * total(b))%mod *total(c))%mod * total(d))%mod; //printf("%lld\n", ans); ans = (ans%mod - join2(a,b,c,d) + mod)%mod; ans = (ans%mod - join2(b,c,a,d) + mod)%mod; ans = (ans%mod - join2(c,d,a,b) + mod)%mod; ans = (ans%mod - join2(d,a,b,c) + mod)%mod; //printf("%lld\n", ans); ans = (ans + join3(a,b,c,d))%mod; ans = (ans + join3(b,c,d,a))%mod; ans = (ans + join3(c,d,a,b))%mod; ans = (ans + join3(a,b,d,c))%mod; //printf("%lld\n", ans); ans = (ans + join2and2(a,b,c,d))%mod; ans = (ans + join2and2(b,c,a,d))%mod; //printf("%lld\n", ans); ans = (ans - 3*join4(a,b,c,d)%mod + mod)%mod; printf("%lld\n", ans); } return 0; } /* 1 15322 17922 8582 14347 107 14823 30138 56661 */