답안 #321308

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
321308 2020-11-12T04:07:01 Z couplefire 무지개나라 (APIO17_rainbow) C++17
12 / 100
920 ms 183288 KB
#include "rainbow.h"
#include <bits/stdc++.h>
using namespace std;
#define MAXN 1<<18

const int SZ = MAXN;
template<class T> struct node {
	T val = 0; node<T>* c[2];
	node() { c[0] = c[1] = NULL; }
	void upd(int ind, T v, int L = 0, int R = SZ-1) { // add v
		if (L == ind && R == ind) { val += v; return; }
		int M = (L+R)/2;
		if (ind <= M) {
			if (!c[0]) c[0] = new node();
			c[0]->upd(ind,v,L,M);
		} else {
			if (!c[1]) c[1] = new node();
			c[1]->upd(ind,v,M+1,R);
		}
		val = 0; for(int i = 0; i<2; i++) if (c[i]) val += c[i]->val;
	}
	T query(int lo, int hi, int L = 0, int R = SZ-1) { // query sum of segment
		if (hi < L || R < lo) return 0;
		if (lo <= L && R <= hi) return val;
		int M = (L+R)/2; T res = 0;
		if (c[0]) res += c[0]->query(lo,hi,L,M);
		if (c[1]) res += c[1]->query(lo,hi,M+1,R);
		return res;
	}
	void UPD(int ind, node* c0, node* c1, int L = 0, int R = SZ-1) { // for 2D segtree
		if (L != R) {
			int M = (L+R)/2;
			if (ind <= M) {
				if (!c[0]) c[0] = new node();
				c[0]->UPD(ind,c0?c0->c[0]:NULL,c1?c1->c[0]:NULL,L,M);
			} else {
				if (!c[1]) c[1] = new node();
				c[1]->UPD(ind,c0?c0->c[1]:NULL,c1?c1->c[1]:NULL,M+1,R);
			}
		} 
		val = (c0?c0->val:0)+(c1?c1->val:0);
	}
};


template<class T> struct Node {
	node<T> seg; Node* c[2];
	Node() { c[0] = c[1] = NULL; }
	void upd(int x, int y, T v, int L = 0, int R = SZ-1) { // add v
		if (L == x && R == x) { seg.upd(y,v); return; }
		int M = (L+R)/2;
		if (x <= M) {
			if (!c[0]) c[0] = new Node();
			c[0]->upd(x,y,v,L,M);
		} else {
			if (!c[1]) c[1] = new Node();
			c[1]->upd(x,y,v,M+1,R);
		}
		seg.upd(y,v); // only for addition
		// seg.UPD(y,c[0]?&c[0]->seg:NULL,c[1]?&c[1]->seg:NULL);
	}
	T query(int x1, int x2, int y1, int y2, int L = 0, int R = SZ-1) { // query sum of rectangle
		if (x1 <= L && R <= x2) return seg.query(y1,y2);
		if (x2 < L || R < x1) return 0;
		int M = (L+R)/2; T res = 0;
		if (c[0]) res += c[0]->query(x1,x2,y1,y2,L,M);
		if (c[1]) res += c[1]->query(x1,x2,y1,y2,M+1,R);
		return res;
	}
};

map<pair<int, int>, int> mp;
set<pair<int, int>> visited;
vector<int> trows[MAXN];
vector<int> tcols[MAXN];
vector<pair<int, int>> rows[MAXN];
vector<pair<int, int>> cols[MAXN];
Node<int> seg;
int minr = MAXN, maxr = -MAXN, minc = MAXN, maxc = -MAXN;

void addSquare(int a, int b){
    if(visited.count({a, b})) return;
    visited.insert({a, b});
    mp[{a, b}]++;
    mp[{a+1, b}]++;
    mp[{a, b+1}]++;
    mp[{a+1, b+1}]++;
    trows[a].push_back(b);
    tcols[b].push_back(a);
    minr = min(minr, a); maxr = max(maxr, a);
    minc = min(minc, b); maxc = max(maxc, b);
}

void init(int R, int C, int sr, int sc, int M, char *S) {
    string s = S;
    addSquare(sr, sc);
    for(auto c : s){
        if(c == 'N') sr--;
        if(c == 'S') sr++;
        if(c == 'W') sc--;
        if(c == 'E') sc++;
        addSquare(sr, sc);
    }
    for(auto p : mp){
        if(p.second == 1) seg.upd(p.first.first, p.first.second, 1);
        if(p.second == 3) seg.upd(p.first.first, p.first.second, -1);
        if(p.second == 2){
            if(visited.count({p.first.first, p.first.second}) && visited.count({p.first.first+1, p.first.second+1})) seg.upd(p.first.first, p.first.second, -2);
            if(visited.count({p.first.first+1, p.first.second}) && visited.count({p.first.first, p.first.second+1})) seg.upd(p.first.first, p.first.second, -2);
        }
    }
    for(int i = 0; i<MAXN; i++) sort(trows[i].begin(), trows[i].end());
    for(int i = 0; i<MAXN; i++) sort(tcols[i].begin(), tcols[i].end());
    for(int i = 0; i<MAXN; i++){
        if(trows[i].empty()) continue;
        int cur = trows[i][0];
        for(int j = 1; j<trows[i].size(); j++){
            if(trows[i][j] != trows[i][j-1]+1){
                rows[i].push_back({cur, trows[i][j-1]});
                cur = trows[i][j];
            }
        }
        rows[i].push_back({cur, trows[i].back()});
    }
    for(int i = 0; i<MAXN; i++){
        if(tcols[i].empty()) continue;
        int cur = tcols[i][0];
        for(int j = 1; j<tcols[i].size(); j++){
            if(tcols[i][j] != tcols[i][j-1]+1){
                cols[i].push_back({cur, tcols[i][j-1]});
                cur = tcols[i][j];
            }
        }
        cols[i].push_back({cur, tcols[i].back()});
    }
    // for(int i = 0; i<MAXN; i++){
    //     if(cols[i].empty()) continue;
    //     cout << i << endl;
    //     for(auto j : cols[i]) cout << j.first << " " << j.second << endl;
    //     cout << endl;
    // }
}

int colour(int ar, int ac, int br, int bc) {
    int ans = 0;
    ans += seg.query(ar+1, br, ac+1, bc);
    int p1, p2;
    // top row
    p1 = lower_bound(rows[ar].begin(), rows[ar].end(), make_pair(ac+1, -1))-rows[ar].begin();
    p2 = lower_bound(rows[ar].begin(), rows[ar].end(), make_pair(bc+1, -1))-rows[ar].begin();
    p1--; p2--;
    if(p1 >= 0 && rows[ar][p1].second >= ac && rows[ar][p1].second < bc) ans--;
    if(p2 >= 0 && rows[ar][p2].first > ac && rows[ar][p2].second >= bc) ans--;
    p1++; if(p2 >= 0 && rows[ar][p2].second >= bc) p2--;
    if(p1 < rows[ar].size() && rows[ar][p1].second < bc && p2 >= 0 && rows[ar][p2].first > ac) ans -= (p2-p1+1)*2;

    p1 = lower_bound(rows[br].begin(), rows[br].end(), make_pair(ac+1, -1))-rows[br].begin();
    p2 = lower_bound(rows[br].begin(), rows[br].end(), make_pair(bc+1, -1))-rows[br].begin();
    p1--; p2--;
    if(p1 >= 0 && rows[br][p1].second >= ac && rows[br][p1].second < bc) ans--;
    if(p2 >= 0 && rows[br][p2].first > ac && rows[br][p2].second >= bc) ans--;
    p1++; if(p2 >= 0 && rows[br][p2].second >= bc) p2--;
    if(p1 < rows[br].size() && rows[br][p1].second < bc && p2 >= 0 && rows[br][p2].first > ac) ans -= (p2-p1+1)*2;

    p1 = lower_bound(cols[ac].begin(), cols[ac].end(), make_pair(ar+1, -1))-cols[ac].begin();
    p2 = lower_bound(cols[ac].begin(), cols[ac].end(), make_pair(br+1, -1))-cols[ac].begin();
    p1--; p2--;
    if(p1 >= 0 && cols[ac][p1].second >= ar && cols[ac][p1].second < br) ans--;
    if(p2 >= 0 && cols[ac][p2].first > ar && cols[ac][p2].second >= br) ans--;
    p1++; if(p2 >= 0 && cols[ac][p2].second >= br) p2--;
    if(p1 < cols[ac].size() && cols[ac][p1].second < br && p2 >= 0 && cols[ac][p2].first > ar) ans -= (p2-p1+1)*2;

    p1 = lower_bound(cols[bc].begin(), cols[bc].end(), make_pair(ar+1, -1))-cols[bc].begin();
    p2 = lower_bound(cols[bc].begin(), cols[bc].end(), make_pair(br+1, -1))-cols[bc].begin();
    p1--; p2--;
    if(p1 >= 0 && cols[bc][p1].second >= ar && cols[bc][p1].second < br) ans--;
    if(p2 >= 0 && cols[bc][p2].first > ar && cols[bc][p2].second >= br) ans--;
    p1++; if(p2 >= 0 && cols[bc][p2].second >= br) p2--;
    if(p1 < cols[bc].size() && cols[bc][p1].second < br && p2 >= 0 && cols[bc][p2].first > ar) ans -= (p2-p1+1)*2;
    if(!visited.count({ar, ac})) ans--;
    if(!visited.count({ar, bc})) ans--;
    if(!visited.count({br, ac})) ans--;
    if(!visited.count({br, bc})) ans--;
    if(ar < minr && br > maxr && ac < minc && bc > maxc) ans -= 4;
    return -ans/4;
}

Compilation message

rainbow.cpp: In function 'void init(int, int, int, int, int, char*)':
rainbow.cpp:117:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  117 |         for(int j = 1; j<trows[i].size(); j++){
      |                        ~^~~~~~~~~~~~~~~~
rainbow.cpp:128:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  128 |         for(int j = 1; j<tcols[i].size(); j++){
      |                        ~^~~~~~~~~~~~~~~~
rainbow.cpp: In function 'int colour(int, int, int, int)':
rainbow.cpp:155:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  155 |     if(p1 < rows[ar].size() && rows[ar][p1].second < bc && p2 >= 0 && rows[ar][p2].first > ac) ans -= (p2-p1+1)*2;
      |        ~~~^~~~~~~~~~~~~~~~~
rainbow.cpp:163:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  163 |     if(p1 < rows[br].size() && rows[br][p1].second < bc && p2 >= 0 && rows[br][p2].first > ac) ans -= (p2-p1+1)*2;
      |        ~~~^~~~~~~~~~~~~~~~~
rainbow.cpp:171:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  171 |     if(p1 < cols[ac].size() && cols[ac][p1].second < br && p2 >= 0 && cols[ac][p2].first > ar) ans -= (p2-p1+1)*2;
      |        ~~~^~~~~~~~~~~~~~~~~
rainbow.cpp:179:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  179 |     if(p1 < cols[bc].size() && cols[bc][p1].second < br && p2 >= 0 && cols[bc][p2].first > ar) ans -= (p2-p1+1)*2;
      |        ~~~^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 20 ms 25068 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 24940 KB Output is correct
2 Correct 18 ms 24940 KB Output is correct
3 Correct 297 ms 40284 KB Output is correct
4 Correct 493 ms 62648 KB Output is correct
5 Correct 649 ms 91868 KB Output is correct
6 Correct 716 ms 104668 KB Output is correct
7 Correct 920 ms 111512 KB Output is correct
8 Correct 110 ms 26084 KB Output is correct
9 Correct 495 ms 62556 KB Output is correct
10 Correct 675 ms 91996 KB Output is correct
11 Correct 757 ms 104540 KB Output is correct
12 Correct 280 ms 48348 KB Output is correct
13 Correct 330 ms 62300 KB Output is correct
14 Correct 488 ms 92020 KB Output is correct
15 Correct 628 ms 104796 KB Output is correct
16 Correct 339 ms 42976 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 24940 KB Output is correct
2 Correct 228 ms 49116 KB Output is correct
3 Correct 192 ms 49160 KB Output is correct
4 Correct 834 ms 183288 KB Output is correct
5 Incorrect 145 ms 43080 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 20 ms 25068 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 20 ms 25068 KB Output isn't correct
2 Halted 0 ms 0 KB -