题面
Alice, Bob, and Carol visit a spring to collect water. Alice visits every days (on days ), Bob visits every days (on days ), and Carol visits every days (on days ).
When only one person visits, they collect liters of water. If multiple people visit, the water is divided equally: two people take liters each, and three people take liters each.
Your task is to calculate how much water Alice, Bob, and Carol collect over days, starting from day .
Input
The first line contains a single integer () — the number of test cases.
The only line of each test case contains four integers , , , and (; ).
Output
For each test case, print three integers — the number of liters of water that Alice, Bob, and Carol collect over days.
思路
先把问题从按天模拟改成按事件计数
第 天谁会来只由整除关系决定
- Alice 来当且仅当
- Bob 来当且仅当
- Carol 来当且仅当
因此前 天内某类事件出现次数都可写成
设
这样设的原因是一个人的收益不仅取决于自己来了多少天 还取决于和别人重合了多少天
以 Alice 为例做容斥修正
- 先按每次来都拿 计入 得到
- 与 Bob 同天时每次应从 变 需减去
- 与 Carol 同天时同理 需减去
- 三人同天在前两步被重复扣减 实际应拿 只需比 少 因此前面多减了 需加回
得到
同理
代码
#include <bits/stdc++.h>
using namespace std;
int main() { int t; cin >> t; while (t --) { long long a, b, c, m; cin >> a >> b >> c >> m;
long long na = m/a, nb = m/b, nc = m/c; long long nab = m/lcm(a,b), nbc = m/lcm(b,c), nac = m/lcm(a,c), nabc = m/lcm(lcm(a, b), c); long long wa = 6*na - 3*nab - 3*nac + 2*nabc, wb = 6*nb - 3*nab - 3*nbc + 2*nabc, wc = 6*nc - 3*nac - 3*nbc + 2*nabc;
cout << wa << " " << wb << " " << wc << endl; }}