Loading [MathJax]/jax/output/CommonHTML/jax.js

문제링크

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

+ Recent posts