문제링크
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 |