第九届山东省赛 Four-tuples

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_ilixiri 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_1x1x2,x2x3,x3x4,x4x1. 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(1T106).
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(1liri109).

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

*/


猜你喜欢

转载自blog.csdn.net/khn64/article/details/80426130