Four-tuples
Time Limit: 2000 ms
Memory Limit: 524288 KiB
Output
For each test case, output one line containing one integer, representing the answer.
Sample Input
1 1 1 2 2 3 3 4 4
Sample Output
1
Hint
Source
2018 Shandong ACM programing real contest, on-site problem replay
解题报告:容斥原理
第一种特殊情况 : x1 = x2 , 第二种特殊情况 : x2 = x3 , 第三种特殊情况 : x3 = x4 , 第四种特殊情况 : x4 = x1
总情况 sum = (r1 - l1 + 1)*(r2 - l2 + 1)*(r3 - l3 + 1)*(r4 - l4 + 1)
总特殊情况:使用容斥定理
需要注意的是 A U B U C 和 A UBUCUD 因为等号具有传递性,所以是一样的,即三交集与四交集都一样。
结果 = 总情况 - 总特殊情况
使用函数:
mo -- 防止中间溢出(这种算法很容易爆long long)
jiao -- 分别求两个,三个,四个集合的交集
注意!这里jiao求的交集,并非容斥定理中的交集,现场时就是弄混了,然后就乱了
代码:
#include<bits/stdc++.h>
using namespace std;
long long mo(long long x)
{
return x % ((long long)1e9 + 7);
}
long long jiao2(int l1, int r1, int l2, int r2)
{
long long ans = min(r1, r2) - max(l1, l2) + 1;
if(ans <= 0)
return 0;
else
return ans;
}
long long jiao3(int l1, int r1, int l2, int r2, int l3,int r3)
{
long long ans = min(r1, min(r2, r3)) - max(l1, max(l2, l3)) + 1;
if(ans <= 0)
return 0;
else
return ans;
}
long long jiao4(int l1, int r1, int l2, int r2, int l3,int r3, int l4, int r4)
{
long long ans = min(min(r1, r2), min(r3, r4)) - max(max(l1, l2), max(l3, l4)) + 1;
if(ans <= 0)
return 0;
else
return ans;
}
int main()
{
int l[8], r[8], t;
long long sum;
scanf("%d", &t);
while(t--)
{
sum = 1;
for(int i = 0; i < 4; i++)
{
scanf("%d%d", &l[i], &r[i]);
l[i + 4] = l[i];
r[i + 4] = r[i];
sum *= (r[i] - l[i] + 1);
sum %= (long long)1e9 + 7;
}
// A + B + C + D 即一交集
for(int i = 0; i < 4; i++)
{
sum -= mo(mo(jiao2(l[i], r[i], l[i + 1], r[i + 1]) * (r[i + 2] - l[i + 2] + 1)) * (r[i + 3] - l[i + 3] + 1));
while(sum < 0) sum += (long long)1e9 + 7;
}
// A U B 即二交集
for(int i = 0; i < 4; i++)
{
sum += jiao3(l[i], r[i], l[i + 1], r[i + 1], l[i + 2], r[i + 2]) * (r[i + 3] - l[i + 3] + 1);
sum %= (long long)1e9 + 7;
}
//二交集中 A U C, B U D
sum += jiao2(l[0], r[0], l[1], r[1]) * jiao2(l[2], r[2], l[3], r[3]);
sum %= (long long)1e9 + 7;
sum += jiao2(l[1], r[1], l[2], r[2]) * jiao2(l[0], r[0], l[3], r[3]);
sum %= (long long)1e9 + 7;
// A U B U C == A U B U C U D 即三交集与四交集
sum -= mo(3 * jiao4(l[0], r[0], l[1], r[1], l[2], r[2], l[3], r[3]) );
while(sum < 0) sum += (long long)1e9 + 7;
printf("%lld\n", sum);
//验证部分
sum = 0;
for(int i = l[0]; i <= r[0]; i++)
for(int j = l[1]; j <= r[1]; j++)
for(int k = l[2]; k <= r[2]; k++)
for(int p = l[3]; p <= r[3]; p++)
{
if(i != j && j != k && k != p && p != i)
{
sum++;
if(sum >= (1e9 + 7))
{
cout << "暴力要挂了" <<endl;
return 0;
sum -= (1e9 + 7);
}
}
}
printf("暴力标准答案:%lld\n", sum);
}
return 0;
}
最后, 我国超算的发展远远超越了美帝的想象,高手在民间。