2018山东省赛F-Four-tuples | 容斥定理

F-Four-tuples

题目描述

Given l 1 , r 1 , l 2 , r 2 , l 3 , r 3 , l 4 , r 4 ,please count the number of four-tuples ( x 1 , x 2 , x 3 , x 4 ) such that l i x i r i and x 1 x 2 , x 2 x 3 , x 3 x 4 , x 4 x 1 .The answer should modulo109+7 before output.

输入描述:

The input consists of several test cases. The first line gives the number of test cases,T(1≤T≤ 10 6 ).
For each test case, the input contains one line with 8 integers l 1 , r 1 , l 2 , r 2 , l 3 , r 3 , l 4 , r 4 .(1 l i r i 10 9 )

输出描述:

For each test case, output one line containing one integer, representing the answer.

示例1

输入
1
1 1 2 2 3 3 4 4
输出
1

题解:

首先看这个题,容易想到是容斥。设事件A为 x 1 x 2 ,事件B为 x 2 x 3 ,事件C为 x 3 x 4 ,事件D为 x 4 x 1
问题要求: | A B C D | ,可以转换成 | U | | A B C D | ,即求 | A B C D | 就行,容斥定理:
这里写图片描述
因为相等的传递性, x 1 = x 2 , x 2 = x 3 , x 3 = x 4 x 1 = x 2 , x 2 = x 3 , x 4 = x 1 x 1 = x 2 , x 3 = x 4 , x 4 = x 1 x 2 = x 3 , x 3 = x 4 , x 4 = x 1 x 1 = x 2 , x 2 = x 3 , x 3 = x 4 , x 4 = x 1 是一样的结果,所以只要减去三倍 | A B C | 就可以了。

代码

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define LL long long

using namespace std;

const int maxn=4;
const int mod=1e9+7;
LL L[maxn],R[maxn];

LL work2(int a,int b) //a==b
{
    LL mL=max(L[a],L[b]);
    LL mR=min(R[a],R[b]);
    if(mR<mL) return 0;
    return (mR-mL+1)%mod;
}

LL work3(int a,int b,int c) //a==b,c==d,e>=0
{
    LL mL1=max(L[a],max(L[b],L[c]));
    LL mR1=min(R[a],min(R[b],R[c]));
    if(mL1>mR1) return 0;
    return (mR1-mL1+1)%mod;
}

LL work4(int a,int b,int c,int d)
{
    LL cnt=1;
    LL mL=max(L[d],max(L[a],max(L[b],L[c])));
    LL mR=min(R[d],min(R[a],min(R[b],R[c])));

    if(mL>mR) return 0;
    return (mR-mL+1)*3%mod;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        for(int i=0; i<maxn; ++i)
            scanf("%lld %lld",&L[i],&R[i]);
        LL ans=1;
        for(int i=0; i<maxn; ++i)
        {
            ans=(ans*(R[i]-L[i]+1))%mod;
        }

        ans=(ans-work2(0,1)*(R[2]-L[2]+1)%mod*(R[3]-L[3]+1)%mod+mod)%mod;//0=1
        ans=(ans-work2(1,2)*(R[0]-L[0]+1)%mod*(R[3]-L[3]+1)%mod+mod)%mod;//1=2
        ans=(ans-work2(2,3)*(R[0]-L[0]+1)%mod*(R[1]-L[1]+1)%mod+mod)%mod;//2=3
        ans=(ans-work2(3,0)*(R[2]-L[2]+1)%mod*(R[1]-L[1]+1)%mod+mod)%mod;//3=0

        ans=(ans+work3(0,1,2)*(R[3]-L[3]+1)%mod)%mod;//0==1,1==2
        ans=(ans+work2(0,1)*work2(2,3)%mod)%mod;//0==1,2==3
        ans=(ans+work3(0,1,3)*(R[2]-L[2]+1)%mod)%mod;//0==1,3==0
        ans=(ans+work3(1,2,3)*(R[0]-L[0]+1)%mod)%mod;//1==2,2==3
        ans=(ans+work2(1,2)*work2(3,0)%mod)%mod;//1==2,3==0
        ans=(ans+work3(2,3,0)*(R[1]-L[1]+1)%mod)%mod;//2==3,3==0

        ans=(ans-work4(0,1,2,3)+mod)%mod;//0==1,1==2,2==3 ->3==0
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/exchan/article/details/80381509