답안 #727510

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
727510 2023-04-20T22:10:48 Z CutSandstone Regions (IOI09_regions) C++17
95 / 100
5818 ms 131072 KB
// #pragma GCC optimize ("Ofast")
// #pragma GCC target ("avx,avx2")
#include <bits/stdc++.h>
#define ll long long
#define vi vector<int>
#define f first
#define s second
#define pb push_back
#define inf ~((long long)1<<63)
using namespace std;
const int mod = 1000000007;
void setio(string name = "") { 
    ios::sync_with_stdio(false), cin.tie(nullptr); 
    if(name.length()) {
        freopen((name + ".in").c_str(), "r", stdin);
        freopen((name + ".out").c_str(), "w", stdout);
    }
}
class BIT {
  private:
    int size;
    vector<int> bit;
  public:
    BIT(int size) : size(size), bit(size + 1) {}
    void add(int ind, int val){for(ind++; ind <= size; ind += ind & -ind) { bit[ind] += val; };}
    int prev(int ind) {
        int total = 0;
        for (ind++; ind > 0; ind -= ind & -ind) { total += bit[ind]; }
        return total;
    }
    int sum(int a, int b){
        return prev(b)-(a == 0 ? 0:prev(a-1));
    }
};
int N, R, timer = 0;
vector<vector<int>> cnt;
vector<int> big;
vector<int> st, en;
vector<vector<int>> g;
vector<vector<int>> ans;
vector<int> nums;
vector<BIT> sums;
void dfs(int s, vector<int>& curr){
    if(big[nums[s]]+1) curr[big[nums[s]]]++;
    else for(int i = 0; i<curr.size(); i++) ans[s][i] = curr[i];
    st[s] = timer++;
    for(int i: g[s]) dfs(i, curr);
    if(big[nums[s]]+1) curr[big[nums[s]]]--;
    en[s] = timer-1;
}
int main() {
    setio();
    int Q; cin >> N >> R >> Q;
    g.resize(N, vector<int>(0));
    nums.resize(N);
    cin >> nums[0];
    for(int i = 1; i<N; i++){
        int par; cin >> par;
        g[par-1].pb(i);
        cin >> nums[i];
    }
    cnt.resize(R, vector<int>(0));
    for(int i = 0; i<N; i++) cnt[--nums[i]].pb(i);
    int sqrt = 1;
    while(sqrt*sqrt <= N) sqrt++;
    big.resize(R, -1);
    int p = 0;
    for(int i = 0; i<R; i++) if(cnt[i].size() >= sqrt) big[i] = p++;
    st.resize(N);
    en.resize(N);
    ans.resize(N, vector<int>(p));
    vector<int> curr(p);
    dfs(0, curr);
    sums.resize(p, BIT(N));
    for(int i = 0; i<N; i++) if(big[nums[i]]+1) sums[big[nums[i]]].add(st[i], 1);
    BIT b(N);
    map<int, int> mem;
    while(Q--> 0){
        int up, down; cin >> up >> down; --up, --down;
        if(mem.find(up*R+down) != mem.end()) cout << mem[up*R+down] << endl;
        else if(big[down]+1){
            int ret = 0;
            for(int i: cnt[up]) ret+=sums[big[down]].sum(st[i], en[i]);
            mem[up*R+down] = ret;
            cout << ret << endl;
        }else if(big[up]+1){
            int ret = 0;
            for(int i: cnt[down])
                ret+=ans[i][big[up]];
            mem[up*R+down] = ret;
            cout << ret << endl;
        }else{
            int ret = 0;
            for(int i: cnt[down]) b.add(st[i], 1);
            for(int i: cnt[up]) ret+=b.sum(st[i], en[i])-(up == down ? 1:0);
            for(int i: cnt[down]) b.add(st[i], -1);
            mem[up*R+down] = ret;
            cout << ret << endl;
        }
    }
}

Compilation message

regions.cpp: In function 'void dfs(int, std::vector<int>&)':
regions.cpp:45:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   45 |     else for(int i = 0; i<curr.size(); i++) ans[s][i] = curr[i];
      |                         ~^~~~~~~~~~~~
regions.cpp: In function 'int main()':
regions.cpp:68:47: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   68 |     for(int i = 0; i<R; i++) if(cnt[i].size() >= sqrt) big[i] = p++;
      |                                 ~~~~~~~~~~~~~~^~~~~~~
regions.cpp: In function 'void setio(std::string)':
regions.cpp:15:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   15 |         freopen((name + ".in").c_str(), "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
regions.cpp:16:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   16 |         freopen((name + ".out").c_str(), "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 208 KB Output is correct
2 Correct 1 ms 208 KB Output is correct
3 Correct 2 ms 208 KB Output is correct
4 Correct 5 ms 336 KB Output is correct
5 Correct 6 ms 400 KB Output is correct
6 Correct 21 ms 464 KB Output is correct
7 Correct 34 ms 516 KB Output is correct
8 Correct 31 ms 592 KB Output is correct
9 Correct 56 ms 1244 KB Output is correct
10 Correct 96 ms 1592 KB Output is correct
11 Correct 127 ms 2212 KB Output is correct
12 Correct 182 ms 3016 KB Output is correct
13 Correct 226 ms 2888 KB Output is correct
14 Correct 313 ms 5180 KB Output is correct
15 Correct 358 ms 8360 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1172 ms 24856 KB Output is correct
2 Correct 1272 ms 18068 KB Output is correct
3 Correct 2335 ms 21944 KB Output is correct
4 Correct 372 ms 4552 KB Output is correct
5 Correct 498 ms 7080 KB Output is correct
6 Correct 510 ms 32488 KB Output is correct
7 Correct 700 ms 36676 KB Output is correct
8 Correct 1237 ms 97136 KB Output is correct
9 Correct 3519 ms 22864 KB Output is correct
10 Runtime error 129 ms 131072 KB Execution killed with signal 9
11 Correct 5818 ms 27960 KB Output is correct
12 Correct 1663 ms 31360 KB Output is correct
13 Correct 2309 ms 33108 KB Output is correct
14 Correct 2881 ms 62868 KB Output is correct
15 Correct 4027 ms 41088 KB Output is correct
16 Correct 4713 ms 46908 KB Output is correct
17 Correct 4791 ms 77264 KB Output is correct