문제링크
https://www.acmicpc.net/problem/25317
25317번: functionx
$x$를 변수로 하는 다항식 $f(x)$가 있다. 처음에 $f(x) =1$이다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. $1$ $a$ $b$: $f(x)$에 $(ax+b)$를 곱한다. $2$ $c$: $f(c)$가 음수라면 -, $0$이라면 0, 양수라
www.acmicpc.net
풀이
다항함수에서 f(c) 의 부호를 결정하는 요소는
- 최고차항의 계수 부호
- 최고차항의 지수
- c 보다 작은 근의 개수
가 있다. 위 세개를 고려해서 부호를 결정하면 되겠다
c 보다 작은 근의 개수를 구하기 위해서 segment tree 를 사용할 수 있겠다
근의 범위가 크므로(+ 정수 값이 아니므로) 대소비교만 알 수 있도록 좌표압축을 해준다.
( PBDS 의 ordered set 을 쓰면 더 간결하게 코드 작성 가능)
1 a b 에서 a = 0 인 경우를 주의
코드
#include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define ll long long
#define ld long double
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pair<int, int> > vpi;
typedef vector<vector<int>> vvi;
typedef pair<ll, ll> pll;
typedef tuple<ll, ll, ll> tlll;
typedef vector<ll> vl;
typedef vector<pair<ll, ll>> vpl;
typedef vector<vector<ll>> vvl;
typedef vector<string> vs;
int dr[4] = {0, 0, 1, -1};
int dc[4] = {1, -1, 0, 0};
// loops
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define F0R(i, a) FOR(i, 0, a)
#define ROF(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i, a) ROF(i, 0, a)
#define rep(a) F0R(_, a)
#define each(a, x) for (auto &a : x)
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
#if !defined(ONLINE_JUDGE)
freopen("../input.txt", "r", stdin);
freopen("../output.txt", "w", stdout);
#endif // ONLINE_JUDGE
int q;
cin >> q;
vector<tuple<ll, ll, ll> > query(q);
vector<tuple<ll, ll, ll> > queryOrg(q);
vector<pair<ld, int> > v(q);
for (int i = 0; i < q; ++i) {
auto& [a, b, c] = query[i];
cin >> a;
if (a == 1) {
cin >> b >> c;
if (b == 0) {
v[i] = {1.0L * 1e30, -1};
} else {
v[i] = {-1.0L * c / b,i};
}
} else {
cin >> b;
v[i] = {b, i};
}
queryOrg[i] = query[i];
}
sort(all(v));
ld prev;
int idx = 1;
for (int i = 0; i < q; ++i) {
if (v[i].second == -1) continue;
auto& [a, b, c] = query[v[i].second];
if (a == 1) {
if (b > 0) b = 1;
else if (b == 0) b = 0;
else b = -1;
if (i && abs(prev - v[i].first) > 1e-25) {
c = ++idx;
} else {
c = idx;
}
} else {
if (i && abs(prev - v[i].first) > 1e-25) {
b = ++idx;
} else {
b = idx;
}
}
prev = v[i].first;
}
vi t(2 * q);
auto update = [&](int p, int v) {
for (t[p += q] = v; p > 1; p >>= 1) t[p >> 1] = t[p] + t[p ^ 1];
};
auto sum = [&](int l, int r) {
int ret = 0;
for (l += q, r += q; l < r; l >>= 1, r >>= 1) {
if (l & 1) ret += t[l++];
if (r & 1) ret += t[--r];
}
return ret;
};
int x = 0;
int sign = 0;
int allzero = false;
for (int i = 0; i < q; ++i) {
auto [a, b, c] = query[i];
if (a == 1) {
if (b == 0) {
if (get<2>(queryOrg[i]) == 0) allzero = true;
else {
if (get<2>(queryOrg[i]) < 0) sign ^= 1;
}
} else {
if (get<1>(queryOrg[i]) < 0) sign ^= 1;
++x;
update(c, t[q + c] + 1);
}
} else {
if (t[q + b] || allzero) cout << 0 << '\n';
else cout << (((sign + x + sum(1, b + 1)) % 2 == 1) ? '-' : '+' )<< '\n';
}
}
}
728x90
'PS > BOJ' 카테고리의 다른 글
백준 25320번: SCV 체인 (C++) (0) | 2023.06.27 |
---|---|
백준 25319번: Twitch Plays VIIIbit Explorer (C++) (0) | 2023.06.23 |
백준 25315번: N수매화검법 (C++) (0) | 2023.06.16 |
백준 1441번: 나누어 질까 (C++) (0) | 2023.06.13 |
백준 16933번: 벽 부수고 이동하기 3 (C++) (1) | 2023.06.11 |