山东省第九届ACM F-Four-tuples(容斥定理)

Given   ,please count the number of four-tuples such thatand  

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≤106).

For each test case, the input contains one line
with 8 integers,.

输出描述:

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

示例1

输入

1
1 1 2 2 3 3 4 4

输出

1

(听说这套题AC5道就稳金了,,,)

题目大意:给出4个区域,每个区域取一个数,求可取的种数。要求

思路:区间有可能互相重叠,所以考虑容斥定理。(只是名字高端而已)所有区域值相乘为总的方案数,需要减去特殊情况下的方案。理一下思路,4个条件为4种事件,那就可能1.2   。1.3 。  1.4。   2.3。   2.4。   3.4。  1.2.3。  1.2.4。  1.3.4。   2.3.4。  1.2.3.4。相交总共11种特殊情况,依次减去即可。(和模拟题一样烦)

代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll l1,r1,l2,r2,l3,r3,l4,r4;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld%lld%lld%lld%lld%lld",&l1,&r1,&l2,&r2,&l3,&r3,&l4,&r4);
        ll len1=(r1-l1+1);
        ll len2=(r2-l2+1);
        ll len3=(r3-l3+1);
        ll len4=(r4-l4+1);
        ll tl,tr,tl2,tr2;
        ll ans=len1*len2%mod;
        ans=ans*len3%mod;
        ans=ans*len4%mod;
        //此时ans为总可能方案数
       //下面进行容斥处理不合法 
        //减去满足一个不等式的
        //1与2交,即减去x1=x2的方案
        tl=max(l1,l2);
        tr=min(r1,r2);
        if(tl<=tr)
            ans=((ans-((tr-tl+1)*len3%mod*len4%mod))%mod+mod)%mod;
        //2与3交,即减去x2=x3的方案
        tl=max(l2,l3);
        tr=min(r2,r3);
        if(tl<=tr)
            ans=((ans-((tr-tl+1)*len1%mod*len4%mod))%mod+mod)%mod;
        //3与4交,即减去x3=x4的方案
        tl=max(l3,l4);
        tr=min(r3,r4);
        if(tl<=tr)
            ans=((ans-((tr-tl+1)*len1%mod*len2%mod))%mod+mod)%mod;
        //4与1交,即减去x4=x1的方案
        tl=max(l1,l4);
        tr=min(r1,r4);
        if(tl<=tr)
            ans=((ans-((tr-tl+1)*len2%mod*len3%mod))%mod+mod)%mod;
        //加上同时满足两个不等式的
        //1,2,3交,在计算1与2交和2与3交时,将1,2,3交的情况减去了两次,所以这里加回来
        //可以理解为,减去x1=x2和x2=x3时,将x1=x2=x3减了两次
        tl=max(l1,max(l2,l3));
        tr=min(r1,min(r2,r3));
        if(tl<=tr)
            ans=(ans+(tr-tl+1)*len4%mod)%mod;
        //1,2,4交
        tl=max(l1,max(l2,l4));
        tr=min(r1,min(r2,r4));
        if(tl<=tr)
            ans=(ans+(tr-tl+1)*len3%mod)%mod;
        //1,3,4交
        tl=max(l1,max(l3,l4));
        tr=min(r1,min(r3,r4));
        if(tl<=tr)
            ans=(ans+(tr-tl+1)*len2%mod)%mod;
        //2,3,4交
        tl=max(l2,max(l3,l4));
        tr=min(r2,min(r3,r4));
        if(tl<=tr)
            ans=(ans+(tr-tl+1)*len1%mod)%mod;
        //1,2交且3,4交
        tl=max(l1,l2);
        tr=min(r1,r2);
        tl2=max(l3,l4);
        tr2=min(r3,r4);
        if(tl<=tr&&tl2<=tr2)
            ans=(ans+(tr-tl+1)*(tr2-tl2+1)%mod)%mod;
        //1,4交且2,3交
        tl=max(l1,l4);
        tr=min(r1,r4);
        tl2=max(l3,l2);
        tr2=min(r3,r2);
        if(tl<=tr&&tl2<=tr2)
            ans=(ans+(tr-tl+1)*(tr2-tl2+1)%mod)%mod;
        //减去同时满足三个不等式的,即x1=x2=x3=x4
        //1,2,3,4交
        tl=max(l4,max(l2,max(l3,l1)));
        tr=min(r4,min(r2,min(r3,r1)));
        if(tl<=tr)
            ans=((ans-((tr-tl+1)*3%mod))%mod+mod)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值