2020牛客NOIP赛前集训营-提高组(第一场)部分题解
A. 牛牛的方程式
数学题。
考虑 \(ax + by = c\) 有解的充要条件是 \(c|\mathrm{gcd}(a, b)\),于是 \(ax + by\) 可以表示的所有整数即为 \(\mathrm{gcd}(a,b)t\)
代入原式:\(\mathrm{gcd}(a,b)t + cz = d\),它有解的充要条件即是 \(d|\mathrm{gcd}(a, b, c).\)
lli a, b, c, d;
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int T; cin >> T;
while (T --> 0) {
cin >> a >> b >> c >> d;
bool ans = false;
lli g = std::__gcd(a, std::__gcd(b, c));;
if (g == 0) ans = (d == 0);
else ans = (d % g == 0);
cout << (ans ? "YES" : "NO") << endl;
}
return 0;
}
B. 牛牛的猜球游戏
宏观考虑每次操作对序列的影响,发现添删后面一个操作就是交换序列中对应的两个位置,添删前面一个操作就是交换序列中对应的两个数。于是在操作过程中维护序列和序列里每个数的位置,然后莫队即可。
const int MAXN = 1e5 + 10;
int n, m;
int blk[MAXN];
struct Qry {
int l, r, id, ansid;
} qrys[MAXN];
bool cmp1(Qry x, Qry y) {
if (blk[x.l] == blk[y.l]) return x.r < y.r;
return blk[x.l] < blk[y.l];
}
bool cmp2(Qry x, Qry y) {
return x.id < y.id;
}
std::vector<int> anss[MAXN];
struct E { int x, y; } ops[MAXN];
int tmp[10], pos[10];
void Add_back(int tp) {
int opx = ops[tp].x, opy = ops[tp].y;
std::swap(pos[tmp[opx]], pos[tmp[opy]]);
std::swap(tmp[opx], tmp[opy]);
}
void Del_back(int tp) {
Add_back(tp);
}
void Del_front(int tp) {
int opx = ops[tp].x, opy = ops[tp].y;
std::swap(tmp[pos[opx]], tmp[pos[opy]]);
std::swap(pos[opx], pos[opy]);
}
void Add_front(int tp) {
Del_front(tp);
}
void CollectAns(int qid) {
qrys[qid].ansid = qid;
rep (i, 0, 9) anss[qid].push_back(tmp[i]);
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m;
int siz = (int) sqrt(n);
rep (i, 1, n) cin >> ops[i].x >> ops[i].y;
rep (i, 0, 9) pos[i] = tmp[i] = i;
rep (i, 1, n) {
blk[i] = (i - 1) / siz + 1;
}
rep (i, 1, m) {
cin >> qrys[i].l >> qrys[i].r; qrys[i].id = i;
} std::sort(qrys + 1, qrys + 1 + m, cmp1);
int pl = 1, pr = 0; // [pl, pr]
for (int i = 1; i <= m; ++i) {
while (pr < qrys[i].r) Add_back(++pr);
while (qrys[i].l < pl) Add_front(--pl);
while (pl < qrys[i].l) Del_front(pl++);
while (qrys[i].r < pr) Del_back(pr--);
CollectAns(i);
}
std::sort(qrys + 1, qrys + 1 + m, cmp2);
rep (i, 1, m) {
rep (j, 0, 9) cout << anss[qrys[i].ansid][j] << ' ';
cout << endl;
}
return 0;
}