18年省赛 F Four-tuples 容斥原理
F-Four-tuples_“浪潮杯”第九届山东省ACM大学生程序设计竞赛重现赛(重现赛)(重现赛)@aquamoon_zjx (nowcoder.com)
写公式的时候, 可以看着图中的某一块, 数它加了多少,减了多少来保证正确性
代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL mod = 1e9+7; int l[5], r[5]; LL f2(int a,int b) { LL lt=max(l[a],l[b]); LL rt=min(r[a],r[b]); return rt-lt+1>0?rt-lt+1:0; } LL f3(int a,int b,int c) { LL lt=max(l[a],max(l[b],l[c])); LL rt=min(r[a],min(r[b],r[c])); return rt-lt+1>0?rt-lt+1:0; } LL f4(int a,int b,int c,int d) { LL lt=max(max(l[a],l[b]),max(l[c],l[d])); LL rt=min(min(r[a],r[b]),min(r[c],r[d])); return rt-lt+1>0?rt-lt+1:0; } int main() { int t; scanf("%d", &t); while(t --) { LL res = 1; for(int i = 1; i <=4; i ++) scanf("%d %d", &l[i], &r[i]);//用scanf, 否则超时 for(int i = 1; i <=4; i ++) res = (res*(r[i]-l[i]+1)%mod)%mod; res = (res - f2(1,2)%mod*(r[3]-l[3]+1)%mod * (r[4]-l[4]+1)%mod+mod)%mod; res = (res - f2(2,3)%mod*(r[1]-l[1]+1)%mod * (r[4]-l[4]+1)%mod+mod)%mod; res = (res - f2(3,4)%mod*(r[1]-l[1]+1)%mod * (r[2]-l[2]+1)%mod+mod)%mod; res = (res - f2(4,1)%mod*(r[3]-l[3]+1)%mod * (r[2]-l[2]+1)%mod+mod)%mod; //S1US2时,包括S3US4; S3US4时,包括S1US2. 这期间重复减去了S1US2且S3US4; res = (res + f2(1,2)%mod*f2(3,4)%mod+mod)%mod; res = (res + f2(3,2)%mod*f2(1,4)%mod+mod)%mod; res = (res + f3(1,2,3)%mod * (r[4]-l[4]+1)%mod)%mod; res = (res + f3(2,3,4)%mod * (r[1]-l[1]+1)%mod)%mod; res = (res + f3(3,4,1)%mod * (r[2]-l[2]+1)%mod)%mod; res = (res + f3(4,1,2)%mod * (r[3]-l[3]+1)%mod)%mod; res = res - f4(1,2,3,4)%mod*3%mod;//这一块的情况 4-4+4, 最后一共加了4次, 需要再减去3次 res = (res+mod)%mod; printf("%lld\n", res); } return 0; } /* S1+S2+S3+S4 - S1∩S2-S2∩S3-S3∩S4-S4∩S1 + S1∩S2∩S3+S2∩S3∩S4+S3∩S4∩S1+S4∩S1∩S2 - S1∩S2∩S3∩S4 */