void Solve() { int ans=0,i,r,k; for (i=1;i+ans<n;i++) { r=BinSearch(i,i+1,n); k=MaxRMQ(i,r); if (len[k]>len[i]) ans=TMax(ans,k-i); } if (ans==0) printf("-1\n"); else printf("%d\n",ans); }
MeshCleaner::MeshCleaner(udword nbVerts, const Point* srcVerts, udword nbTris, const udword* srcIndices) { Point* cleanVerts = (Point*)ICE_ALLOC(sizeof(Point)*nbVerts); ASSERT(cleanVerts); // memcpy(cleanVerts, srcVerts, nbVerts*sizeof(Point)); udword* indices = (udword*)ICE_ALLOC(sizeof(udword)*nbTris*3); udword* remapTriangles = (udword*)ICE_ALLOC(sizeof(udword)*nbTris); const float meshWeldTolerance = 0.01f; udword* vertexIndices = null; if(meshWeldTolerance!=0.0f) { vertexIndices = (udword*)ICE_ALLOC(sizeof(udword)*nbVerts); const float weldTolerance = 1.0f / meshWeldTolerance; // snap to grid for(udword i=0; i<nbVerts; i++) { vertexIndices[i] = i; cleanVerts[i] = Point( floorf(srcVerts[i].x*weldTolerance + 0.5f), floorf(srcVerts[i].y*weldTolerance + 0.5f), floorf(srcVerts[i].z*weldTolerance + 0.5f)); } } else { memcpy(cleanVerts, srcVerts, nbVerts*sizeof(Point)); } const udword maxNbElems = TMax(nbTris, nbVerts); const udword hashSize = NextPowerOfTwo(maxNbElems); const udword hashMask = hashSize-1; udword* hashTable = (udword*)ICE_ALLOC(sizeof(udword)*(hashSize + maxNbElems)); ASSERT(hashTable); memset(hashTable, 0xff, hashSize * sizeof(udword)); udword* const next = hashTable + hashSize; udword* remapVerts = (udword*)ICE_ALLOC(sizeof(udword)*nbVerts); memset(remapVerts, 0xff, nbVerts * sizeof(udword)); for(udword i=0;i<nbTris*3;i++) { const udword vref = srcIndices[i]; if(vref<nbVerts) remapVerts[vref] = 0; } udword nbCleanedVerts = 0; for(udword i=0;i<nbVerts;i++) { if(remapVerts[i]==0xffffffff) continue; const Point& v = cleanVerts[i]; const udword hashValue = getHashValue(v) & hashMask; udword offset = hashTable[hashValue]; while(offset!=0xffffffff && cleanVerts[offset]!=v) offset = next[offset]; if(offset==0xffffffff) { remapVerts[i] = nbCleanedVerts; cleanVerts[nbCleanedVerts] = v; if(vertexIndices) vertexIndices[nbCleanedVerts] = i; next[nbCleanedVerts] = hashTable[hashValue]; hashTable[hashValue] = nbCleanedVerts++; } else remapVerts[i] = offset; } udword nbCleanedTris = 0; for(udword i=0;i<nbTris;i++) { udword vref0 = *srcIndices++; udword vref1 = *srcIndices++; udword vref2 = *srcIndices++; if(vref0>=nbVerts || vref1>=nbVerts || vref2>=nbVerts) continue; // PT: you can still get zero-area faces when the 3 vertices are perfectly aligned const Point& p0 = srcVerts[vref0]; const Point& p1 = srcVerts[vref1]; const Point& p2 = srcVerts[vref2]; const float area2 = ((p0 - p1)^(p0 - p2)).SquareMagnitude(); if(area2==0.0f) continue; vref0 = remapVerts[vref0]; vref1 = remapVerts[vref1]; vref2 = remapVerts[vref2]; if(vref0==vref1 || vref1==vref2 || vref2==vref0) continue; indices[nbCleanedTris*3+0] = vref0; indices[nbCleanedTris*3+1] = vref1; indices[nbCleanedTris*3+2] = vref2; nbCleanedTris++; } ICE_FREE(remapVerts); udword nbToGo = nbCleanedTris; nbCleanedTris = 0; memset(hashTable, 0xff, hashSize * sizeof(udword)); Indices* I = reinterpret_cast<Indices*>(indices); bool idtRemap = true; for(udword i=0;i<nbToGo;i++) { const Indices& v = I[i]; const udword hashValue = getHashValue(v) & hashMask; udword offset = hashTable[hashValue]; while(offset!=0xffffffff && I[offset]!=v) offset = next[offset]; if(offset==0xffffffff) { remapTriangles[nbCleanedTris] = i; if(i!=nbCleanedTris) idtRemap = false; I[nbCleanedTris] = v; next[nbCleanedTris] = hashTable[hashValue]; hashTable[hashValue] = nbCleanedTris++; } } ICE_FREE(hashTable); if(vertexIndices) { for(udword i=0;i<nbCleanedVerts;i++) cleanVerts[i] = srcVerts[vertexIndices[i]]; ICE_FREE(vertexIndices); } mNbVerts = nbCleanedVerts; mNbTris = nbCleanedTris; mVerts = cleanVerts; mIndices = indices; if(idtRemap) { ICE_FREE(remapTriangles); mRemap = NULL; } else { mRemap = remapTriangles; } }
void TMax::Load(TSIn& SIn) { *this = TMax(SIn); }