DID : PS 1문제 (2023/04/05)

DID : PS 1문제 (2023/04/05)

시험 공부 중 한문제 슬쩍 풀었다.

BOJ 16978 수열과 쿼리 22
PST로 풀린다고 해서 풀어볼려 했는데, 오프라인 쿼리로 풀릴 거 같아서 느낌 그대로 조져 보았다. 그냥 합 연산인데 오프라인 쿼리를 곁들인? 쿼리1,2를 저장해서 쿼리 2를 정렬하고, 쿼리 1을 순차적으로 해결해 나가면 된다. EZ

#include<bits/stdc++.h>
#define ppiipii pair<pair<int,int>, pair<int,int> >
using namespace std;
typedef long long ll;
vector<pair<int,int> > query1;
vector<ppiipii > query2;
ll ans[100005];

struct Node
{
    ll v;
    Node *l, *r;
    Node(){l = r = NULL, v = 0;}
    Node(Node *l, Node *r, int v){this->l = l; this->r = r; this-> v = v;}
};
ll arr[(int)1e5+7];
Node root;

void init(Node *node, int s,int e)
{
    if(s == e)
    {
        node->v = (ll)arr[s];
        return;
    }
    int mid = (s+e)/2;
    node->l = new Node(); init(node->l,s,mid);
    node->r = new Node(); init(node->r,mid+1, e);
    node->v = (node->l->v) + (node->r->v);
}
ll query(Node *node, int s,int e, int a,int b)
{
    if(a <= s and e <= b) return node->v;
    if(b < s or e < a) return 0LL;
    int mid = (s+e)/2;
    return query(node->l,s,mid,a,b) + query(node->r, mid+1,e,a,b);
}
void update(Node *node, int s,int e, int x, int v)
{
    if(x < s or e < x) return;
    else if(s == e)
        node->v = v;
    else
    {
        int mid = (s+e)/2;
        update(node->l,s,mid,x,v);
        update(node->r, mid+1, e,x,v);
        node->v = node->l->v + node->r->v;
    }
}
int main()
{
    int n; scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%lld", arr+i);
    init(&root, 1, n);
    int Q; scanf("%d", &Q);
    int query2num = 0;
    query1.push_back({0,0});
    while(Q--)
    {
        int a; scanf("%d",&a);
        int b,c,d;
        switch(a)
        {
        case 1:
            scanf("%d %d",&b,&c);
            query1.push_back({b,c});
            break;
        case 2:
            scanf("%d %d %d", &b,&c,&d);
            query2.push_back({{b,++query2num},{c,d}});
        }
    }
    sort(query2.begin(),query2.end());
    auto l = query2.begin();

    int m = query1.size();
    for(int i=0; i<m; i++)
    {
        update(&root,1,n,query1[i].first, query1[i].second);
        while(l->first.first == i)
            ans[l->first.second] = query(&root, 1,n,l->second.first, l->second.second), l++;
    }
    for(int i = 1; i <= query2num; i++) printf("%lld\n", ans[i]);
}