int lca(int u, int v){ static int ts = 0; ts ++; while(1){ if( u != -1 ){ u = ffa(u); if(vt[u] == ts) return u; vt[u] = ts; if(pr[u] != -1) u = bk[pr[u]]; else u = -1; } swap(u, v); } return u; }
void flower(int u, int w){ while(u != w){ int v1 = pr[u], v2 = bk[v1]; if(ffa(v2) != w) bk[v2] = v1; if(mtp[v1] == 1){ qu.push(v1); mtp[v1] = 0; } if(mtp[v2] == 1){ qu.push(v2); mtp[v2] = 0; } djo(v1, w); djo(v2, w); djo(u, w); u = v2; } }
bool flow(int s){ memset(mtp, -1, sizeof(mtp)); while(qu.size()) qu.pop(); qu.push(s); mtp[s] = 0; bk[s] = pr[s] = -1; while(qu.size() && pr[s] == -1){ int u = qu.front(); qu.pop(); for(int v=0; v<V; v++){ if (el[u][v] == 0) continue; if (ffa(v) == ffa(u)) continue; if(pr[v] == -1){ do{ int t = pr[u]; pr[v] = u; pr[u] = v; v = t; u = t==-1?-1:bk[t]; }while( v != -1 ); break; }else if(mtp[v] == 0){ int w = lca(u, v); if(ffa(w) != ffa(u)) bk[u] = v; if(ffa(w) != ffa(v)) bk[v] = u; flower(u, w); flower(v, w); }else if(mtp[v] != 1){ bk[v] = u; mtp[v] = 1; mtp[pr[v]] = 0; qu.push(pr[v]); } } } return pr[s] != -1; }
int ffa(int a){ return (djs[a] == -1) ? a : djs[a] = ffa(djs[a]); }
void djo(int a, int b){ int fa = ffa(a), fb = ffa(b); if (fa != fb) djs[fb] = fa; }
/*------------------------------------------------------------------------------------- * Name cepitch - Cepstrum Pitch estimator * * Synopsis (double) f0 = cepitch( * double flo, // Lowest possible f0 * double fh, // Highest possible f0 * double fmax, // Maximum frequency in spectrum * int npt, // Number of points in the spectrum * float *s // an npt-point array containing log spectrum * ); * * Description Windows the spectrum array "s" (assumed to be a log magnitude spectrum) * and computes its DFT (formally the cepstrum). Then searches the region * of the cepstrum associated with f0 values between flo and fhi. It returns * the f0 value associated with the largest magnitude quefrency in the * searched range. *------------------------------------------------------------------------------------- */ double cepitch(double flo, double fhi, double fmax, int npt, float *s) { double fsc, f0, v, vr, vi, vmax, r, rx, cepSecond; float *c, sm, ym1, y, yp1; int nft, j, k, ib, ie; double eavg; nft = 16; while (nft < npt) nft += nft; c = (float *) malloc((nft + 2) * sizeof(float)); fsc = (double) npt / fmax; ie = (int) (4000.0 * fsc + 0.5); if (ie > npt) ie = npt; rx = 3.1415927 / (double) ie; r = 0.0; sm = s[0]; for (j=0; j<ie; j++) { c[j] = (s[j] - sm) * (float) (0.5 + 0.5*cos(r)); sm = s[j]; } for (j=ie; j<nft+2; j++) c[j] = 0.0f; for (k=1; k<3; k++) { ym1 = c[0]; y = c[1]; for (j=1; j<ie; j++) { yp1 = c[j+1]; c[j] = .25f*ym1 + .5f*y + .25f*yp1; ym1 = y; y = yp1; } } ffa(c, nft); /* * Search the requested region for the highest peak and return the associated f0. * * fsc = npt / fmax / nft * ib = 1.0 / fhi / fsc * ie = 1.0 / flo / fsc * f0 = 1.0 / (i * fsc) */ vmax = cepSecond = 0.0; f0 = 0.0; fsc = (double) npt / fmax; fsc /= (double) nft; ib = (int) ((1.0 / fhi) / fsc + 0.5); ie = (int) ((1.0 / flo) / fsc + 0.5); for (j=ib, eavg=(double)0.0; j<=ie; j++) { vr = c[j*2]; vi = c[j*2+1]; v = vr*vr + vi*vi; eavg += v; if (v > vmax) { if(vmax > cepSecond) cepSecond = vmax; /* save second-largest peak */ cepSize = vmax = v; f0 = 1.0f / ((float) j * fsc); } } cepRatio = cepSecond / vmax; free(c); return f0; }