답안 #536075

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
536075 2022-03-12T09:31:47 Z 79brue Inside information (BOI21_servers) C++14
100 / 100
932 ms 281060 KB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct Fenwick {
    int n = 300000;
    int tree[300002];

    void add(int x, int v){
        while(x<=n){
            tree[x] += v;
            x += x&-x;
        }
    }

    int sum(int x){
        int ret = 0;
        while(x){
            ret += tree[x];
            x -= x&-x;
        }
        return ret;
    }

    int sum(int l, int r){
        return sum(r) - sum(l-1);
    }
} tree;

int n, q;
char qt[300002];
int qa[300002], qb[300002];
int qans[300002];
vector<pair<int, int> > link[300002];
vector<int> increasingVec[300002];

void makeCentroidTree();
bool query(int, int, int);
void query(int, int);
void processQueries();

int main(){
    scanf("%d %d", &n, &q);
    q += n-1;
    for(int i=1; i<=q; i++){
        scanf(" %c %d", &qt[i], &qa[i]);
        if(qt[i]!='C') scanf("%d", &qb[i]);
        if(qt[i]=='S') link[qa[i]].push_back(make_pair(qb[i], i)), link[qb[i]].push_back(make_pair(qa[i], i));
    }
    for(int i=1; i<=n; i++){
        sort(link[i].begin(), link[i].end(), [&](auto x, auto y){
            return x.second < y.second;
        });
    }

    makeCentroidTree();
    for(int i=1; i<=n; i++) sort(increasingVec[i].begin(), increasingVec[i].end());
    for(int i=1; i<=q; i++){
        if(qt[i] == 'C'){
            query(qa[i], i);
            qans[i] += upper_bound(increasingVec[qa[i]].begin(), increasingVec[qa[i]].end(), i) - increasingVec[qa[i]].begin();
            qans[i] += 1;
        }
    }
    processQueries();

    for(int i=1; i<=q; i++){
        if(qt[i]=='S') continue;
        if(qt[i]=='Q'){
            printf("%s\n", query(qa[i], qb[i], i) ? "yes" : "no");
        }
        else{
            printf("%d\n", qans[i]);
        }
    }
}

int centroidRoot;
vector<int> centroidChild[300002];
int centroidDepth[300002], centroidPar[300002], centroidAncestor[300002][20];
bool centroidUsed[300002];
int subTreeSize[300002];

bool increasing[300002][20], decreasing[300002][20];
int rootLinkWeight[300002][20], parWeight[300002][20];
int rootLink[300002][20];
vector<pair<int, int> > vec[300002];
vector<pair<int, int> > vecSpecific[300002][20];

struct Query {
    int t; /// 0: 점 추가, 1: 쿼리
    int x, y, w, i;
    Query(){}
    Query(int t, int x, int y, int w, int i): t(t), x(x), y(y), w(w), i(i){}

    bool operator<(const Query &r)const{
        if(y==r.y) return t<r.t;
        return y<r.y;
    }
};
vector<Query> queries[300002];

void subTreeDfs(int x, int p=-1){
    subTreeSize[x] = 1;
    for(auto y: link[x]){
        if(y.first==p || centroidUsed[y.first]) continue;
        subTreeDfs(y.first, x);
        subTreeSize[x] += subTreeSize[y.first];
    }
}

void getCentroid(int x, int p, int &c, int lim){
    if(subTreeSize[x] < lim) return;
    c = x;
    for(auto y: link[x]){
        if(y.first==p || centroidUsed[y.first]) continue;
        getCentroid(y.first, x, c, lim);
    }
}

void makeDatabase(int x, int p, int dp, int parWeight1, int rootWeight1, bool inc, bool dec, int root, int underRoot){
    increasing[x][dp] = inc, decreasing[x][dp] = dec;
    rootLinkWeight[x][dp] = rootWeight1, parWeight[x][dp] = parWeight1;
    rootLink[x][dp] = underRoot;
    if(inc){
        vec[root].push_back(make_pair(rootWeight1, parWeight1));
        vecSpecific[underRoot][dp].push_back(make_pair(rootWeight1, parWeight1));
        increasingVec[root].push_back(parWeight1);
    }

    for(auto y: link[x]){
        if(y.first==p || centroidUsed[y.first]) continue;
        makeDatabase(y.first, x, dp, y.second, rootWeight1, inc && parWeight1 < y.second, dec && parWeight1 > y.second,
                     root, underRoot);
    }
}

int findCentroid(int x, int dp=0){
    subTreeDfs(x);
    int s = subTreeSize[x];
    int c = x, lim = (s+1)/2;
    getCentroid(x, -1, c, lim);
    centroidUsed[c] = 1;
    centroidDepth[c] = dp;

    for(auto y: link[c]){
        if(centroidUsed[y.first]) continue;
        makeDatabase(y.first, c, dp, y.second, y.second, 1, 1, c, y.first);
    }

    for(auto y: link[c]){
        if(centroidUsed[y.first]) continue;
        int tmp = findCentroid(y.first, dp+1);
        centroidPar[tmp] = c;
        centroidChild[c].push_back(tmp);
    }
    return c;
}

void makeCentroidTree(){
    centroidRoot = findCentroid(1);
    for(int i=1; i<=n; i++) centroidAncestor[i][centroidDepth[i]] = i;
    for(int i=1; i<=n; i++){
        int dp = centroidDepth[i];
        for(int j=dp-1; j>=0; j--) centroidAncestor[i][j] = centroidPar[centroidAncestor[i][j+1]];
    }
}

bool query(int A, int B, int i){
    if(A==B) return true;
    swap(A, B);
    int d=min(centroidDepth[A], centroidDepth[B]);
    while(centroidAncestor[A][d] != centroidAncestor[B][d]) d--;
    int root = centroidAncestor[A][d];

    if(root == A) return increasing[B][d] && parWeight[B][d] <= i;
    if(root == B) return decreasing[A][d] && rootLinkWeight[A][d] <= i;
    return decreasing[A][d] && increasing[B][d] && rootLinkWeight[A][d] < rootLinkWeight[B][d] && parWeight[B][d] <= i;
}

void query(int x, int i){
    for(int d=centroidDepth[x]-1; d>=0; d--){
        if(!decreasing[x][d]) continue;
        if(i >= rootLinkWeight[x][d]) qans[i]++;
        queries[centroidAncestor[x][d]].push_back(Query(1, rootLinkWeight[x][d]+1, i, 1, i));
    }
}

void processQueries(){
    for(int i=1; i<=n; i++){
        sort(vec[i].begin(), vec[i].end());
        for(int d=0; d<20; d++){
            sort(vecSpecific[i][d].begin(), vecSpecific[i][d].end());
        }
    }

    for(int i=1; i<=n; i++){
        vector<Query> qvec = queries[i];
        for(pair<int, int> p: vec[i]) qvec.push_back(Query(0, p.first, p.second, 1, 0));
        sort(qvec.begin(), qvec.end());

        for(Query query: qvec){
            if(query.t == 0) tree.add(query.x, query.w);
            else qans[query.i] += tree.sum(query.x, tree.n);
        }
        for(Query query: qvec){
            if(query.t == 0) tree.add(query.x, -query.w);
        }
    }
}

Compilation message

servers.cpp: In function 'int main()':
servers.cpp:45:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   45 |     scanf("%d %d", &n, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~
servers.cpp:48:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   48 |         scanf(" %c %d", &qt[i], &qa[i]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
servers.cpp:49:29: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   49 |         if(qt[i]!='C') scanf("%d", &qb[i]);
      |                        ~~~~~^~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 131 ms 178292 KB Output is correct
2 Correct 148 ms 180332 KB Output is correct
3 Correct 142 ms 180564 KB Output is correct
4 Correct 149 ms 180728 KB Output is correct
5 Correct 145 ms 180240 KB Output is correct
6 Correct 136 ms 180104 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 131 ms 178292 KB Output is correct
2 Correct 148 ms 180332 KB Output is correct
3 Correct 142 ms 180564 KB Output is correct
4 Correct 149 ms 180728 KB Output is correct
5 Correct 145 ms 180240 KB Output is correct
6 Correct 136 ms 180104 KB Output is correct
7 Correct 140 ms 179144 KB Output is correct
8 Correct 156 ms 183828 KB Output is correct
9 Correct 147 ms 184460 KB Output is correct
10 Correct 155 ms 184840 KB Output is correct
11 Correct 166 ms 184380 KB Output is correct
12 Correct 161 ms 184228 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 134 ms 178304 KB Output is correct
2 Correct 294 ms 236884 KB Output is correct
3 Correct 318 ms 236824 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 134 ms 178304 KB Output is correct
2 Correct 294 ms 236884 KB Output is correct
3 Correct 318 ms 236824 KB Output is correct
4 Correct 135 ms 178752 KB Output is correct
5 Correct 300 ms 238752 KB Output is correct
6 Correct 286 ms 237768 KB Output is correct
7 Correct 295 ms 240348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 129 ms 178236 KB Output is correct
2 Correct 516 ms 247556 KB Output is correct
3 Correct 504 ms 247624 KB Output is correct
4 Correct 455 ms 265184 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 129 ms 178236 KB Output is correct
2 Correct 516 ms 247556 KB Output is correct
3 Correct 504 ms 247624 KB Output is correct
4 Correct 455 ms 265184 KB Output is correct
5 Correct 142 ms 178892 KB Output is correct
6 Correct 524 ms 253780 KB Output is correct
7 Correct 534 ms 281060 KB Output is correct
8 Correct 620 ms 255544 KB Output is correct
9 Correct 498 ms 255544 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 131 ms 178312 KB Output is correct
2 Correct 532 ms 253120 KB Output is correct
3 Correct 463 ms 239900 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 131 ms 178312 KB Output is correct
2 Correct 532 ms 253120 KB Output is correct
3 Correct 463 ms 239900 KB Output is correct
4 Correct 129 ms 178988 KB Output is correct
5 Correct 612 ms 270104 KB Output is correct
6 Correct 456 ms 246328 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 167 ms 178224 KB Output is correct
2 Correct 466 ms 247592 KB Output is correct
3 Correct 538 ms 247608 KB Output is correct
4 Correct 490 ms 265120 KB Output is correct
5 Correct 131 ms 178368 KB Output is correct
6 Correct 526 ms 252908 KB Output is correct
7 Correct 443 ms 239912 KB Output is correct
8 Correct 529 ms 238008 KB Output is correct
9 Correct 568 ms 238428 KB Output is correct
10 Correct 663 ms 250288 KB Output is correct
11 Correct 649 ms 249936 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 167 ms 178224 KB Output is correct
2 Correct 466 ms 247592 KB Output is correct
3 Correct 538 ms 247608 KB Output is correct
4 Correct 490 ms 265120 KB Output is correct
5 Correct 131 ms 178368 KB Output is correct
6 Correct 526 ms 252908 KB Output is correct
7 Correct 443 ms 239912 KB Output is correct
8 Correct 529 ms 238008 KB Output is correct
9 Correct 568 ms 238428 KB Output is correct
10 Correct 663 ms 250288 KB Output is correct
11 Correct 649 ms 249936 KB Output is correct
12 Correct 131 ms 178888 KB Output is correct
13 Correct 554 ms 253780 KB Output is correct
14 Correct 553 ms 281016 KB Output is correct
15 Correct 530 ms 255564 KB Output is correct
16 Correct 542 ms 255552 KB Output is correct
17 Correct 137 ms 179912 KB Output is correct
18 Correct 592 ms 270188 KB Output is correct
19 Correct 503 ms 246328 KB Output is correct
20 Correct 558 ms 244612 KB Output is correct
21 Correct 575 ms 245028 KB Output is correct
22 Correct 774 ms 276832 KB Output is correct
23 Correct 932 ms 271388 KB Output is correct
24 Correct 847 ms 264844 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 129 ms 178296 KB Output is correct
2 Correct 154 ms 180436 KB Output is correct
3 Correct 159 ms 180428 KB Output is correct
4 Correct 139 ms 180520 KB Output is correct
5 Correct 139 ms 180144 KB Output is correct
6 Correct 183 ms 180092 KB Output is correct
7 Correct 141 ms 178252 KB Output is correct
8 Correct 298 ms 236868 KB Output is correct
9 Correct 324 ms 236824 KB Output is correct
10 Correct 129 ms 178240 KB Output is correct
11 Correct 518 ms 247508 KB Output is correct
12 Correct 519 ms 247556 KB Output is correct
13 Correct 458 ms 265204 KB Output is correct
14 Correct 133 ms 178300 KB Output is correct
15 Correct 541 ms 252868 KB Output is correct
16 Correct 493 ms 239760 KB Output is correct
17 Correct 496 ms 238072 KB Output is correct
18 Correct 561 ms 238416 KB Output is correct
19 Correct 664 ms 250368 KB Output is correct
20 Correct 606 ms 249888 KB Output is correct
21 Correct 353 ms 237416 KB Output is correct
22 Correct 317 ms 237424 KB Output is correct
23 Correct 452 ms 237516 KB Output is correct
24 Correct 407 ms 237616 KB Output is correct
25 Correct 614 ms 245852 KB Output is correct
26 Correct 558 ms 237900 KB Output is correct
27 Correct 551 ms 237616 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 129 ms 178296 KB Output is correct
2 Correct 154 ms 180436 KB Output is correct
3 Correct 159 ms 180428 KB Output is correct
4 Correct 139 ms 180520 KB Output is correct
5 Correct 139 ms 180144 KB Output is correct
6 Correct 183 ms 180092 KB Output is correct
7 Correct 141 ms 178252 KB Output is correct
8 Correct 298 ms 236868 KB Output is correct
9 Correct 324 ms 236824 KB Output is correct
10 Correct 129 ms 178240 KB Output is correct
11 Correct 518 ms 247508 KB Output is correct
12 Correct 519 ms 247556 KB Output is correct
13 Correct 458 ms 265204 KB Output is correct
14 Correct 133 ms 178300 KB Output is correct
15 Correct 541 ms 252868 KB Output is correct
16 Correct 493 ms 239760 KB Output is correct
17 Correct 496 ms 238072 KB Output is correct
18 Correct 561 ms 238416 KB Output is correct
19 Correct 664 ms 250368 KB Output is correct
20 Correct 606 ms 249888 KB Output is correct
21 Correct 353 ms 237416 KB Output is correct
22 Correct 317 ms 237424 KB Output is correct
23 Correct 452 ms 237516 KB Output is correct
24 Correct 407 ms 237616 KB Output is correct
25 Correct 614 ms 245852 KB Output is correct
26 Correct 558 ms 237900 KB Output is correct
27 Correct 551 ms 237616 KB Output is correct
28 Correct 133 ms 179040 KB Output is correct
29 Correct 180 ms 183728 KB Output is correct
30 Correct 148 ms 184460 KB Output is correct
31 Correct 154 ms 184928 KB Output is correct
32 Correct 178 ms 184272 KB Output is correct
33 Correct 150 ms 184228 KB Output is correct
34 Correct 152 ms 179592 KB Output is correct
35 Correct 321 ms 241392 KB Output is correct
36 Correct 286 ms 239412 KB Output is correct
37 Correct 301 ms 242280 KB Output is correct
38 Correct 134 ms 179680 KB Output is correct
39 Correct 541 ms 253652 KB Output is correct
40 Correct 581 ms 281016 KB Output is correct
41 Correct 551 ms 255516 KB Output is correct
42 Correct 541 ms 255532 KB Output is correct
43 Correct 144 ms 179812 KB Output is correct
44 Correct 622 ms 270132 KB Output is correct
45 Correct 534 ms 246328 KB Output is correct
46 Correct 608 ms 244556 KB Output is correct
47 Correct 535 ms 245024 KB Output is correct
48 Correct 772 ms 276960 KB Output is correct
49 Correct 900 ms 271400 KB Output is correct
50 Correct 818 ms 264752 KB Output is correct
51 Correct 307 ms 243920 KB Output is correct
52 Correct 321 ms 245284 KB Output is correct
53 Correct 278 ms 242724 KB Output is correct
54 Correct 338 ms 240612 KB Output is correct
55 Correct 286 ms 243844 KB Output is correct
56 Correct 449 ms 243836 KB Output is correct
57 Correct 589 ms 253220 KB Output is correct
58 Correct 643 ms 255972 KB Output is correct
59 Correct 527 ms 243980 KB Output is correct