Four-tuples (2018山东省省赛 容斥定理)

感谢大佬的博客:

https://blog.csdn.net/qq_41021816/article/details/80328475

开始的时候不知道如何求满足性质pi的元素个数,知道参考了上面的大佬的博客才明白。

还有就是要知道这中取模的,如果ans要减的话,在减之后必须要加上mod在取模才行。

代码:

#include <iostream>     
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
/* 刚开始打算这样做,实在是太傻了。
void fun(int i)
{
    if(arrl[i]>arrr[ (i+1)%4 ])
        flag[i]=0;
    else if( arrl[i]>=arrl[ (i+1)%4 ]&&arrr[ (i+1)%4 ]>=arrl[i]&&arrr[ (i+1)%4 ]<=arrr[i] )
    {
        flag[i]=arrr[ (i+1)%4 ]-arrl[i]+1;
        temp[i][0]=arrl[i],temp[i][1]=arrr[ (i+1)%4 ];
    }    
    else if( arrl[ (i+1)%4 ]<=arrl[i]&&arrr[ (i+1)%4 ]>=arrr[i] )
    {
        flag[i]=arrr[i]-arrl[i]+1;
        temp[i][0]=arrl[i],temp[i][1]=arrr[i];
    }
    else if( arrl[i]<=arrl[  (i+1)%4 ]&&arrr[i]>=arrr[ (i+1)%4 ] )
    {
        flag[i]=arrr[ (i+1)%4 ]-arrl[(i+1)%4]+1;
        temp[i][0]=arrl[(i+1)%4]+1,temp[i][1]=arrr[ (i+1)%4 ];
    }
    else if( arrl[ (i+1)%4 ]>=arrl[i]&&arrl[ (i+1)%4 ] <=arrr[i]&&arrr[ (i+1)%4 ]>=arrr[i] )
    {
        flag[i]=arrr[i]-arrl[ (i+1)%4 ]+1;
        temp[i][0]=arrl[ (i+1)%4 ],temp[i][1]=arrr[i];
    }
    else if(arrl[ (i+1)%4 ]>arrr[i] )
        flag[i]=0;        
}*/ 

int main()
{
    int T;
    scanf("%d",&T);
    ll l1,r1,l2,r2,l3,r3,l4,r4;
    ll acl,acr;
    ll accl,accr;
    ll flag[10];   
    ll ans=0;
    while(T--)            
    {
        scanf("%lld %lld %lld %lld %lld %lld %lld %lld",&l1,&r1,&l2,&r2,&l3,&r3,&l4,&r4);
        ans=(r1-l1+1)%mod*(r2-l2+1)%mod*(r3-l3+1)%mod*(r4-l4+1)%mod;   //为零的时候应该是不存在的。
        ll temp;
        //x1==x2
        acl=max( l1,l2 );
        acr=min(r1,r2);
        temp=acr-acl+1;
        ll temp12=temp;
        if(acr>=acl)    //做题做多了就行了。 
            ans=( ans-( temp*(r3-l3+1)%mod*(r4-l4+1)%mod)+mod )%mod;     
        //x2==x3;
        acl=max(l2,l3);
        acr=min(r2,r3);
        temp=acr-acl+1;
        ll temp23=temp;
        if(temp>0)
            ans=(ans-( temp*(r1-l1+1)%mod*(r4-l4+1)%mod) + mod )%mod;
        //x3==x4;
        acl=max(l4,l3);
        acr=min(r4,r3);
        temp=acr-acl+1;
        ll temp34=temp;
        if(temp>0)
            ans=(ans-( temp*(r1-l1+1)%mod*(r2-l2+1)%mod) +mod)%mod;
        //x4==x1;
        acl=max(l1,l4);
        acr=min(r1,r4);
        temp=acr-acl+1;
        ll temp41=temp;
        if(temp>0)
            ans=(ans-( temp*(r2-l2+1)%mod*(r3-l3+1)%mod)+mod )%mod;
        //x1==x2&&x2==x3;
        acl=max( l1,l2 );
        acr=min(r1,r2);
        temp=acr-acl+1;      
        if(temp>0)
        {
            accl=max( acl,l3 );
            accr=min( acr,r3 );
            temp=accr-accl+1;
            if(temp>0)            //最后的时候还要进行取与吗, 
                ans=(ans%mod+( temp*(r4-l4+1)%mod )%mod )%mod;    
        }
        //x1==x2&&x3==x4; 
        acl=max( l1,l2 );    
        acr=min(r1,r2);                 
        temp=acr-acl+1;
        if(temp>0&&temp34>0 )
        {
             ans=(ans%mod+temp%mod*(temp34%mod)%mod)%mod;    
        }
        //x1==x2&&x4==x1;    //使用简便方法来实现吧。 
        acl=max( l1,l2 );
        acr=min(r1,r2);
        temp=acr-acl+1;      
        if(temp>0)
        {
            accl=max( acl,l4 );
            accr=min( acr,r4 );
            temp=accr-accl+1;
            if(temp>0)            //最后的时候还要进行取与吗, 
                ans=(ans%mod+( temp%mod*(r3-l3+1)%mod )%mod )%mod;    
        }
        //x2==x3&&x3==x4;
        acl=max( l3,l2 );
        acr=min(r3,r2);
        temp=acr-acl+1;      
        if(temp>0)
        {
            accl=max( acl,l4 );
            accr=min( acr,r4 );
            temp=accr-accl+1;
            if(temp>0)            //最后的时候还要进行取与吗, 
                ans=(ans%mod+( temp%mod*(r1-l1+1)%mod )%mod )%mod;    
        }
        //x2==x3&&x4==x1;
        if(temp23>0&&temp41>0)
        {
            ans=(ans%mod+temp23%mod*(temp41%mod)%mod)%mod;    
        } 
        //x3==x4&&x4==x1;
        acl=max( l3,l4 );
        acr=min( r3,r4 );
        temp=acr-acl+1;      
        if(temp>0)                  
        {
            accl=max( acl,l1 );
            accr=min( acr,r1 );
            temp=accr-accl+1;
            if(temp>0)            //最后的时候还要进行取与吗, 
                ans=(ans%mod+( temp%mod*(r2-l2+1)%mod )%mod )%mod;    
        }
        //都相等的情况。 
        acl=max(max( l1,l2 ),max(l3,l4) );
        acr=min( min( r1,r2 ),min(r3,r4));       
        temp=acr-acl+1;
        if(temp>0)               //情况有几种。 
        {
            //temp=(temp*3)%mod;
            ans=(ans%mod-temp*3%mod+ mod)%mod;         
        }
        printf("%lld\n",ans);             
    }
    return 0;    
}

猜你喜欢

转载自blog.csdn.net/weixin_40799464/article/details/82716791