백준14897 서로 다른 수와 쿼리 1 작성일 2019-09-11 | In PS 문제 링크 http://icpc.me/14897 사용 알고리즘 Mo’s Algorithm 풀이 이 문제는 오프라인으로 처리해도 됩니다. 모스 알고리즘을 이용하면 쉽게 풀 수 있습니다. 1234# pragma GCC optimize ("O3") # pragma GCC optimize ("Ofast") # pragma GCC optimize ("unroll-loops") # pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2") pragma 붙이니까 4~500ms정도 빨라지네요. 전체 코드 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970# pragma GCC optimize ("O3") # pragma GCC optimize ("Ofast") # pragma GCC optimize ("unroll-loops") # pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2") #include <bits/stdc++.h> using namespace std; int sqrtN = 2000; struct Query{ int idx, s, e; bool operator < (Query &x){ if(s/sqrtN != x.s/sqrtN) return s/sqrtN < x.s/sqrtN; return e < x.e; } }; vector<int> v, tmp; vector<Query> query; int n, q; int mp[1010101]; vector<int> ans; int now = 0; void sub(int i){ mp[v[i]]--; if(mp[v[i]] == 0) now--; } void add(int i){ if(mp[v[i]] == 0) now++; mp[v[i]]++; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; v.resize(n+1); for(int i=1; i<=n; i++) cin >> v[i]; tmp = v; sort(tmp.begin()+1, tmp.end()); tmp.erase(unique(tmp.begin()+1, tmp.end()), tmp.end()); for(int i=1; i<=n; i++){ v[i] = lower_bound(tmp.begin(), tmp.end(), v[i]) - tmp.begin(); } cin >> q; query.resize(q); ans.resize(q); for(int i=0; i<q; i++){ cin >> query[i].s >> query[i].e; query[i].idx = i; } sort(query.begin(), query.end()); int s = query[0].s; int e = query[0].e; int idx = query[0].idx; for(int i=s; i<=e; i++) add(i); ans[idx] = now; for(int i=1; i<q; i++){ idx = query[i].idx; while(s < query[i].s) sub(s++); while(s > query[i].s) add(--s); while(e < query[i].e) add(++e); while(e > query[i].e) sub(e--); ans[idx] = now; } for(auto i : ans) cout << i << "\n"; }