cafelier のSRM参加記録です。コンテスト中に考えてたことを執拗に全部書き残すとどうなるだろうかという試み本番中にこういうコードが書きたかったなあ、という後で書いた反省コードを書き残す試み
スパムが来たのでしばらくコメント欄をはてなユーザ限定にしています、すみません、
左下にある点の個数と右下にある点の個数を2パスで数えて3パス目で集計したけれど、1パスでできるなあと気づいて感心して書き直した物。
template<typename T=LL> struct FenwickTree { vector<T> x; FenwickTree(size_t n) : x(n) {} void incr( int k, const T& a ) { // z[k] += a; for(; k < x.size(); k|=k+1) x[k] += a; } T sum(int i, int j) { // Sigma z[i,j) excl. return sum_impl(j-1) - sum_impl(i-1); } T sum_impl(int j) { // Sigma z[0,j] incl. T v = T(); for(; j>=0; j=(j&(j+1))-1) v += x[j]; return v; } }; template<typename T> std::vector<int> compress(std::vector<T>& xs) { std::vector< pair<T,int> > xi; for(int i=0; i<xs.size(); ++i) xi.push_back( make_pair(xs[i], i) ); sort(xi.begin(), xi.end()); std::vector<int> result(xs.size()); for(int k=0; k<xi.size(); ++k) result[xi[k].second] = k; return result; } class ThreePoints { public: long long countColoring(int N, int xzero, int xmul, int xadd, int xmod, int yzero, int ymul, int yadd, int ymod) { vector<int> x(N), y(N); x[0] = xzero; for(int i=1; i<N; ++i) x[i] = (x[i-1] * LL(xmul) + xadd) % xmod; y[0] = yzero; for(int i=1; i<N; ++i) y[i] = (y[i-1] * LL(ymul) + yadd) % ymod; x = compress(x); y = compress(y); vector< pair<int,int> > y_desc; for(int i=0; i<N; ++i) y_desc.push_back(make_pair(y[i], x[i])); sort(y_desc.rbegin(), y_desc.rend()); LL result = 0; FenwickTree<> p(N), sp(N); for(int i=0; i<N; ++i) { const int x = y_desc[i].second; LL sp_ = p.sum(x+1, N); LL ssp_ = sp.sum(x+1, N); p.incr(x, 1); sp.incr(x, sp_); result += sp_*(sp_-1)/2 - ssp_; } return result; } };
presented by cafelier/k.inaba under