Beispiel #1
0
pair<size_t, size_t> lowerb(size_t node, size_t L, size_t R, size_t rl, size_t rr, pair<size_t, size_t> minval) {
    if (rl <= L and R <= rr) {
        auto it = std::lower_bound(segm[node].begin(), segm[node].end(), minval);
        if (it == segm[node].end())
            return make_pair(SIZE_MAX, SIZE_MAX);
        else
            return *it;
    }
    if (R <= rl or rr <= L)
        return make_pair(SIZE_MAX, SIZE_MAX);

    size_t mid = L + (R - L) / 2;
    return min(lowerb(2 * node + 1, L, mid, rl, rr, minval)
              ,lowerb(2 * node + 2, mid, R, rl, rr, minval));
}
Beispiel #2
0
/*
 * Blocked Jacobi solver: one iteration step
 */
double relax_jacobi (double *u, double *utmp, unsigned sizex, unsigned sizey)
{
    double diff, sum=0.0;
    int howmany=omp_get_max_threads();
    
#pragma omp parallel reduction(+:sum)
    {
        
        for (int blockid = 0; blockid < howmany; ++blockid) {
            int i_start = lowerb(blockid, howmany, sizex);
            int i_end = upperb(blockid, howmany, sizex);
            for (int i=max(1, i_start); i<= min(sizex-2, i_end); i++) {
#pragma omp for nowait private(diff)
                for (int j=1; j<= sizey-2; j++) {
                    utmp[i*sizey+j]= 0.25 * ( u[ i*sizey     + (j-1) ]+  // left
                                             u[ i*sizey     + (j+1) ]+  // right
                                             u[ (i-1)*sizey + j     ]+  // top
                                             u[ (i+1)*sizey + j     ]); // bottom
                    diff = utmp[i*sizey+j] - u[i*sizey + j];
                    sum += diff * diff;
                }
            }
        }
        
    }
    
    return sum;
}
Beispiel #3
0
/*
 * Blocked Gauss-Seidel solver: one iteration step
 */
double relax_gauss (double *u, unsigned sizex, unsigned sizey)
{
    double unew, diff, sum = 0.0;
    
    int howmany = omp_get_max_threads();
    int numBlocs = 8;
    int blocsProcesats[howmany];
    for(int i = 0; i < howmany; ++i) blocsProcesats[i] = 0;
    
#pragma omp parallel for schedule(static) private(diff,unew) reduction(+: sum)
    for(int i = 0; i < howmany; i++){
        int ii_start = lowerb(i,howmany,sizex);
        int ii_end = upperb(i,howmany,sizex);
        for (int j = 0; j < numBlocs; j++){
            int jj_start = lowerb(j,numBlocs,sizey);
            int jj_end = upperb(j,numBlocs,sizey);
            if(i > 0){
                while(blocsProcesats[i-1]<=j){
#pragma omp flush
                }
            }
            
            for(int ii = max(1,ii_start); ii<= min(sizex-2, ii_end); ii++){
                for(int jj= max(1,jj_start); jj<= min(sizey-2, jj_end); jj++){
                    unew = 0.25* (u[ii * sizey + (jj-1)] +  // left
                                  u[ii * sizey + (jj+1)] +  // right
                                  u[(ii-1) * sizey + jj] +  // top
                                  u[(ii+1) * sizey + jj]); // bottom
                    diff = unew - u[ii * sizey + jj];
                    sum+= diff*diff;
                    u[ii*sizey + jj]  = unew;
                }
            }
            ++blocsProcesats[i];
#pragma omp flush
        }
    }
    
    return sum;
}
Beispiel #4
0
int main() {
    std::iostream::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    size_t n, q;
    cin >> n >> q;
    
    for (size_t i = 1; i != n; ++i)
        graph[input<size_t>() - 1].push_back(i);

    dfs(0);
    buildseg(0, 0, MAXN);
    
    for (size_t i = 0; i != q; ++i) {
        size_t v = input<size_t>() - 1;
        cout << lowerb(0, 0, MAXN, times[v].first, times[v].second, make_pair((sizes[v] + 1) / 2, 0)).second + 1 << "\n";
    }
    
    return 0;
}