左神アルゴリズム学習日記——単調スタック
2281 ワード
単調なスタックは、左右の境界を見つけることができるデータ構造です.
// ( ) ( )
int maxhist(vector hist)
{
stack max;
int res = INT_MIN;
for (int i = 0; i < hist.size(); i++)
{
// , , , , ,
while (!max.empty() && hist[max.top()] >= hist[i])
{
int h = hist[max.top()];
max.pop();
int l = max.size() == 0 ? -1 : max.top();
res = std::max(res, (i - l - 1)*h);
}
max.push(i);
}
// ,
while (!max.empty())
{
int h = hist[max.top()];
max.pop();
int l = max.size() == 0 ? -1 : max.top();
res = std::max(res, (int)(hist.size() - l - 1)*h);
}
return res;
}
int maxmat(vector> mat)
{
vector hist = mat[0];
int res = maxhist(hist);
// , , ,
for (int i = 1; i < mat.size(); i++)
{
for (int j = 0; j < hist.size(); j++)
hist[j] = mat[i][j] == 0 ? 0 : hist[j] + 1;
res = std::max(res, maxhist(hist));
}
return res;
}
// ,
int getteam(int time)
{
return time>1 ? time*(time - 1) / 2 : 0;
}
// ,
int getneigh(vector arr)
{
int maxindex;
for (int i = 0; i < arr.size(); i++)
{
maxindex = arr[maxindex] < arr[i] ? i : maxindex;//
}
int res=0;
stack> dull;
dull.push({ arr[maxindex], 1 });// , , ,
int index=(maxindex+1)%arr.size();
while (index != maxindex)
{
while (arr[index]>dull.top().first)// , , ,
{
pair temp = dull.top();
dull.pop();
res += getteam(temp.second) + 2 * temp.second;
}
if (arr[index] == dull.top().first)
dull.top().second++;
else
dull.push({ arr[index], 1 });
index = (index + 1) % arr.size();
}
while (!dull.empty())
{
pair temp = dull.top();
dull.pop();
res += getteam(temp.second);
if (!dull.empty())
{
res += temp.second;
if (dull.size() > 1)// 2 ,
res += temp.second;
else// 2 , , ,
res += dull.top().second > 1 ? temp.second:0;
}
}
}