1. 程式人生 > >Four-tuples (2018山東省省賽 容斥定理)

Four-tuples (2018山東省省賽 容斥定理)

感謝大佬的部落格:

開始的時候不知道如何求滿足性質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;     }