Skip to main content
  1. Posts/
  2. Algorithm/

BOJ 30880 쿼리는 락이 아니다

·406 words·2 mins
Jiho Kim
Author
Jiho Kim
달려 또 달려

📝 문제 정보
#

🧐 관찰 및 접근
#

  • 누가봐도 세그먼트트리 세팅인것같다. 금광같은거죠
  • 노드 정의를 어떻게 하면 좋을까?
    • 부분열이니까, R / O / C / K 개수는 당연히 있어야하고..
    • ROCK 개수는 ROCK개수 + 왼쪽 R + 오른쪽 OCK, RO + CK, ROC + K,,
    • 아하, R / RO / ROC / ROCK / O / OC / OCK / C / CK / K 다 세면 되나?
  • 아 그런데, ROCK의 개수를 세는게 아니라 ROCK로 끝나는 문자열의 개수를 세야한다는건, 길이도 어떻게 잘 곱해야되는것같은데
    • $XRRX$ 와 $XOCK$ 를 합친다고 생각해보자.
    • 답은 $XRROCK, XROCK, XROCK, RROCK, ROCK, ROCK$로 6개인것 같다.
    • 뒤에 $OCK$근처에서는 별 감흥이 없는 것 같고, 앞에있는 $R$들에 대해서만 상관이 있는 것 같다. 그 위치들에 대해, $2 + 4$ 해서 6이 나온 것 같다.
    • 노드 안에서 $R$에 대해, $R$의 개수가 아니라 $R$로 끝나는 부분 문자열의 개수를 저장하는게 좋겠다.
    • R, RO, ROC, ROCK에 대해서 그렇게 해주면 충분하다!

💻 풀이
#

  • 코드 (C++):
struct Node{
    mint R = 0, RO = 0, ROC = 0, ROCK = 0, O = 0, OC = 0, OCK = 0, C = 0, CK = 0, K = 0;
    mint len = 0;
    mint ans = 0;
    Node(){};
    Node(char c){
        if(c == 'R') R += 1;
        if(c == 'O') O += 1;
        if(c == 'C') C += 1;
        if(c == 'K') K += 1;
        len = 1;
    };
};

Node pull(Node a, Node b){
	Node ret;
	ret.R = a.R + mint(2).pow(a.len.val)*b.R;
	ret.O = a.O + b.O;
	ret.C = a.C + b.C;
	ret.K = a.K + b.K;
	ret.RO = a.RO + mint(2).pow(a.len.val)*b.RO + a.R*b.O;
	ret.OC = a.OC + b.OC + a.O*b.C;
	ret.CK = a.CK + b.CK + a.C*b.K;
	ret.ROC = a.ROC + mint(2).pow(a.len.val)*b.ROC + a.RO*b.C + a.R*b.OC;
	ret.OCK = a.OCK + b.OCK + a.OC*b.K + a.O*b.CK;
	ret.ROCK = a.ROCK + mint(2).pow(a.len.val)*b.ROCK + a.ROC*b.K + a.RO*b.CK + a.R*b.OCK;
	ret.len = a.len + b.len;
	return ret;
}

void solve(){
    int N; cin >> N;
    string S; cin >> S;
    vector<Node> v(N);
    rep(i, 0, N) v[i] = Node(S[i]);
    SegmentTreeNode ST(N, v);

    int Q; cin >> Q;
    while(Q--){
        int op; cin >> op;
        if(op == 1){
            int idx; cin >> idx;
            char c; cin >> c;
            ST.set(idx-1, Node(c));
        }
        else{
            int l, r; cin >> l >> r;
            l--; r--;
            cout << ST.query(l, r).ROCK << '\n';
        }
    }
}
🔒

구현 코드 잠금

아래 쿠팡 링크를 방문하시면 코드가 공개됩니다.
광고 수익이 블로그 운영에 도움이 됩니다 🙏

🛒 쿠팡 방문하고 코드 보기

방문 후 잠금이 자동으로 해제됩니다