Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : Make n00b_land Great Again!
Source            : Hackerearth
Category          : Data Structure, Search
Algorithm         : Parallel Binary Search
Verdict           : Accepted
- #include "bits/stdc++.h"  
-   
- using namespace std;  
-   
- #define FI              freopen("in.txt", "r", stdin)  
- #define FO              freopen("out.txt", "w", stdout)  
- #define FAST            ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)  
-   
- #define FOR(i, n)       for (int i = 1; i <= n; i++)  
- #define For(i, n)       for (int i = 0; i < n; i++)  
- #define ROF(i, n)       for (int i = n; i >= 1; i--)  
- #define Rof(i, n)       for (int i = n-1; i >= 0; i--)  
- #define FORI(i, n)      for (auto i : n)  
- #define REP(i, a, b)    for (int i = a; i <= b; i++)  
-   
- #define ll              long long  
- #define ull             unsigned long long  
- #define vi              vector <int>  
- #define vl              vector <ll>  
- #define pii             pair <int, int>  
- #define pll             pair <ll, ll>  
- #define mk              make_pair  
- #define ff              first  
- #define ss              second  
- #define eb              emplace_back  
- #define em              emplace  
- #define pb              push_back  
- #define ppb             pop_back  
- #define All(a)          a.begin(), a.end()  
- #define memo(a, b)      memset(a, b, sizeof a)  
- #define Sort(a)         sort(All(a))  
- #define ED(a)           Sort(a), a.erase(unique(All(a)), a.end())  
- #define rev(a)          reverse(All(a))  
- #define sz(a)           (int)a.size()  
- #define max3(a, b, c)   max(a, max(b, c))  
- #define min3(a, b, c)   min(a, min(b, c))  
- #define maxAll(a)       *max_element(All(a))  
- #define minAll(a)       *min_element(All(a))  
- #define allUpper(a)     transform(All(a), a.begin(), :: toupper)  
- #define allLower(a)     transform(All(a), a.begin(), :: tolower)  
- #define endl            '\n'  
- #define nl              puts("")  
- #define ub              upper_bound  
- #define lb              lower_bound  
- #define Exp             exp(1.0)  
- #define PIE             2*acos(0.0)  
- #define Sin(a)          sin(((a)*PIE)/180.0)  
- #define EPS             1e-9  
-   
- #include "ext/pb_ds/assoc_container.hpp"  
- #include "ext/pb_ds/tree_policy.hpp"  
- using namespace __gnu_pbds;  
-   
- template <typename T> using orderset = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;  
-   
- #include "ext/rope"  
-   
- using namespace __gnu_cxx;  
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
- #define trace1(x)                           cerr << #x << ": " << x << endl;  
- #define trace2(x, y)                        cerr << #x << ": " << x << " | " << #y << ": " << y << endl;  
- #define trace3(x, y, z)                     cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;  
- #define trace4(a, b, c, d)                  cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;  
- #define trace5(a, b, c, d, e)               cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;  
- #define trace6(a, b, c, d, e, f)            cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;  
-   
- inline int setbit(int mask, int pos)        { return mask |= (1 << pos); }  
- inline int resetbit(int mask, int pos)      { return mask &= ~(1 << pos); }  
- inline int togglebit(int mask, int pos)     { return mask ^= (1 << pos); }  
- inline bool checkbit(int mask, int pos)     { return (bool)(mask & (1 << pos)); }  
-   
- #define popcount(mask)                       __builtin_popcount(mask) // count set bit  
- #define popcountLL(mask)                     __builtin_popcountll(mask) // for long long  
-   
- inline int read()                           { int a; scanf("%d", &a); return a; }  
- inline ll readLL()                          { ll a; scanf("%lld", &a); return a; }  
- inline double readDD()                      { double a; scanf("%lf", &a); return a; }  
-   
- template <typename T> string toString(T num) { stringstream ss; ss << num; return ss.str(); }  
- int toInt(string s)                          { int num; istringstream iss(s); iss >> num; return num;  }  
- ll toLLong(string s)                         { ll num; istringstream iss(s); iss >> num; return num; }  
-   
- #define inf             1e17  
- #define mod             1000000007  
-   
- static const int maxn = 5e5 + 5;  
- static const int logn = 20;  
-   
-   
- int tnode, towners, tquery;  
- vector <int> graph[maxn];  
- vector <int> owner[maxn];  
- vector <int> toCheck[maxn];  
- ll required[maxn];  
- int qn[maxn];  
- ll qx[maxn], qd[maxn]; 
- int lo[maxn], hi[maxn];  
- int N;   
- int depth[maxn], father[maxn][logn];  
- int subtreeSize[maxn];  
-   
- inline void dfs(int u = 1, int p = -1)  
- {  
-       FOR(i, logn-1) father[u][i] = father[ father[u][i-1] ][i-1];  
-       subtreeSize[u] = 1;  
-       FORI(v, graph[u])  
-       {  
-             if (v == p) continue;  
-             depth[v] = depth[u] + 1;  
-             father[v][0] = u;  
-             dfs(v, u);  
-             subtreeSize[u] += subtreeSize[v];  
-       }  
- }  
-   
- int chainHead[maxn], chainNo, chainInd[maxn],  
-     baseArray[maxn], posBase[maxn], ptr;  
-   
- inline void hld(int u = 1, int p = -1)  
- {  
-       if (chainHead[chainNo] == 0) chainHead[chainNo] = u;  
-       ptr++;  
-       baseArray[ptr] = 0;  
-       posBase[u] = ptr;  
-       chainInd[u] = chainNo;  
-       int mx = -1;  
-       int bigChild = -1;  
-       FORI(v, graph[u])  
-       {  
-             if (v == p) continue;  
-             if (subtreeSize[v] > mx) mx = subtreeSize[v], bigChild = v;  
-       }  
-       if (bigChild != -1) hld(bigChild, u);  
-       FORI(v, graph[u])  
-       {  
-             if (v == p || v == bigChild) continue;  
-             ++chainNo;  
-             hld(v, u);  
-       }  
- }  
-   
- struct tupple  
- {  
-       ll sumX, sumD, sumDD;  
-       tupple(ll x = 0, ll d = 0, ll dd = 0) : sumX(x), sumD(d), sumDD(dd) {}  
-   
-       inline void add(const tupple &tpl)  
-       {  
-             sumX += tpl.sumX;  
-             sumD += tpl.sumD;  
-             sumDD += tpl.sumDD;  
-       }  
- };  
-   
- tupple BTree[maxn];  
-   
- inline void update(int pos, tupple val)  
- {  
-       while (pos <= N)  
-       {  
-             BTree[pos].add(val);  
-             pos += (pos & -pos);  
-       }  
- }  
-   
- inline tupple query(int pos)  
- {  
-       tupple tpl = tupple();  
-       while (pos > 0)  
-       {  
-             tpl.add(BTree[pos]);  
-             pos -= (pos & -pos);  
-       }  
-       return tpl;  
- }  
-   
- inline tupple getSum(int l, int r)  
- {  
-       tupple Left = query(l-1);  
-       tupple Right = query(r);  
-       tupple ans = tupple();  
-       ans.sumX = Right.sumX - Left.sumX;  
-       ans.sumD = Right.sumD - Left.sumD;  
-       ans.sumDD = Right.sumDD - Left.sumDD;  
-       return ans;  
- }  
-   
- inline tupple query_path(int u, int v)  
- {  
-       tupple res = tupple();  
-       int uChain;  
-       int vChain = chainInd[v];  
-       while (true)  
-       {  
-             uChain = chainInd[u];  
-             if (uChain == vChain)  
-             {  
-                   int l = posBase[v];  
-                   int r = posBase[u];  
-                   assert(l <= r);  
-                   tupple q = getSum(l, r);  
-                   res.add(q);  
-                   break;  
-             }  
-             int l = posBase[ chainHead[uChain] ];  
-             int r = posBase[u];  
-             assert(l <= r);  
-             tupple q = getSum(l, r);  
-             res.add(q);  
-             u = father[ chainHead[uChain] ][0];  
-       }  
-       return res;  
- }  
-   
- inline void update_hld(int nodeInd)  
- {  
-       int node = qn[nodeInd];  
-       ll x = qx[nodeInd];  
-       ll d = qd[nodeInd];  
-       ll dd = depth[node] * d * 1LL;  
-       int pos = posBase[node];  
-       update(pos, tupple(x, d, dd));  
- }  
-   
- inline void recover(int nodeInd)  
- {  
-       int node = qn[nodeInd];  
-       ll x = qx[nodeInd];  
-       ll d = qd[nodeInd];  
-       ll dd = depth[node] * d * 1LL;  
-       int pos = posBase[node];  
-       update(pos, tupple(-x, -d, -dd));  
- }  
-   
- int main()  
- {  
-         
-       tnode = read();  
-       towners = read();  
-       REP(v, 2, tnode)  
-       {  
-             int u = read();  
-             graph[u].eb(v);  
-       }  
-       FOR(i, tnode)  
-       {  
-             int own = read();  
-             owner[own].eb(i);  
-       }  
-       FOR(i, towners) required[i] = readLL();  
-       tquery = read();  
-       FOR(i, tquery)  
-       {  
-             qn[i] = read();  
-             qx[i] = readLL();  
-             qd[i] = readLL();  
-       }  
-       depth[1] = 1;  
-       dfs();  
-       hld();  
-       N = ptr;  
-       FOR(i, towners) lo[i] = 1, hi[i] = tquery+1;  
-       while (true)  
-       {  
-             FOR(i, N) BTree[i] = tupple();  
-             bool updateRqd = false;  
-             int maxq = -1;  
-             FOR(i, towners)  
-             {  
-                   if (lo[i] != hi[i])  
-                   {  
-                         updateRqd = true;  
-                         int mid = (lo[i] + hi[i]) / 2;  
-                         if (mid > maxq) maxq = mid;  
-                         toCheck[mid].eb(i);  
-   
-                   }  
-             }  
-             if (updateRqd == false) break;  
-             FOR(qq, maxq)  
-             {  
-                   update_hld(qq);  
-                   FORI(id, toCheck[qq])  
-                   {  
-                         ll sum = 0;  
-                         FORI(u, owner[id])  
-                         {  
-                               tupple qry = query_path(u, 1);  
-                               ll sum_x = qry.sumX;  
-                               ll sum_d = qry.sumD;  
-                               ll sum_dd = qry.sumDD;  
-                               ll add = depth[u] * sum_d * 1LL;  
-                               sum = sum + sum_x + add - sum_dd;  
-                               if (sum >= required[id]) break;  
-                         }  
-                         if (sum >= required[id]) hi[id] = qq;  
-                         else lo[id] = qq + 1;  
-                   }  
-                   toCheck[qq].clear();  
-             }  
-       }  
-       FOR(i, towners)  
-       {  
-             if (lo[i] <= tquery) printf("%d\n", lo[i]);  
-             else puts("rekt");  
-       }  
- }  
 
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.