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; }