0x11をスタック
スタックは、LIFOの線形データ構造
成るスタック分41機能をAcWing
これは現在の最小記録するために、2つのスタック、他の単調スタックの値を記録するスタックを維持する
符号化
128エディタをAcWing
2つのスタックのメンテナンス、ヒープの先頭に同様の操作を開き、我々はトップの良いスタック彼に電話します
オーダー\(P \)カーソル位置に、それぞれ開いて2つのスタック\(B \)
スタック\(A \)預金\(P \)スタックの前に数\(Bの預金\) Pの$の後に番号
\(SUM \)は接頭辞であり、\(F \)は、プレフィックスと最大値であります
操作のための\(Lの\) 、\(X \)スタック上に\(\)と更新\(SUM \)と\(F \)
操作のための\(D \) 、スタック\(\)スタックポップ
操作のために\(Lの\) 、スタックの最上位\(\)がポップアップし、スタックにプッシュ\(B \)
操作のために\(R&LT \) 、スタックの最上位(\ Bの\)がポップアップし、スタックにプッシュ\(A \) 、更新\(SUM \)と\(F \)
操作のための\(Q \) 、戻り\(\ [X] F)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5 , INF = 0x7ffffff;
int T , opt , a[N] , b[N] , sum[N] , f[N] , ta = 0 , tb = 0;
inline int read( bool _ )
{
register int x = 0 , f_ = 1;
register char ch = getchar();
if( _ )
{
while( ch < '0' || ch > '9' )
{
if( ch == '-' ) f_ = -1;
ch = getchar();
}
while( ch >= '0' && ch <= '9')
{
x = ( x << 3 ) + ( x << 1 ) + ch - '0';
ch = getchar();
}
return x * f_;
}
else
{
while( ch != 'L' && ch != 'R' && ch != 'I' && ch != 'D' && ch != 'Q' ) ch = getchar();
return int(ch);
}
}
inline void work_1()
{
a[ ++ ta ] = read(1);
sum[ta] = sum[ ta - 1 ] + a[ta];
f[ta] = max( sum[ta] , f[ ta - 1] );
return ;
}
inline void work_2()
{
if( ta > 0 ) ta --;
return ;
}
inline void work_3()
{
if( ta > 0 )b[ ++ tb] = a[ ta ] , ta --;
return ;
}
inline void work_4()
{
if( !tb ) return ;
a[ ++ ta ] = b[tb];
tb --;
sum[ta] = sum[ta - 1] + a[ta];
f[ta] = max( sum[ta] , f[ ta - 1] );
return ;
}
inline void work_5()
{
printf("%d\n",f[ read(1) ] );
return ;
}
int main()
{
f[0] = -INF;
T = read(1);
while( T -- )
{
opt = read(0);
if(opt == 'I' ) work_1();
else if(opt == 'D' ) work_2();
else if(opt == 'L' ) work_3();
else if(opt == 'R' ) work_4();
else work_5();
}
return 0;
}
131ヒストグラム最大の長方形をAcWing
サンプルは、描画の手法を遊んで見つけることができます
単調な古典的なアプリケーションのスタックが、私は怠け者、STL + O2直接水の過去
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#define LL long long
using namespace std;
const int N = 100005;
int n , now , width ;
LL res;
struct node
{
int w , h;
}_;
stack< node > s;
inline int read()
{
register int x = 0;
register char ch = getchar();
while( ch < '0' || ch > '9' ) ch = getchar();
while( ch >= '0' && ch <= '9' )
{
x = ( x << 3 ) + ( x << 1 ) + ch - '0';
ch = getchar();
}
return x;
}
inline node make( int x , int y )
{
_.h = x , _.w = y;
return _;
}
int main()
{
while( 1 )
{
n = read();
if( !n ) return 0;
res = 0;
for( register int i = 1; i <= n ; i ++ )
{
now = read();
if( s.empty() || now > s.top().h ) s.push( make( now , 1 ) );
else
{
width = 0;
while( !s.empty() && s.top().h > now )
{
width += s.top().w;
res = max( res , (LL)width * s.top().h );
s.pop();
}
s.push( make( now , width + 1 ) );
}
}
width = 0;
while( !s.empty() )
{
width += s.top().w;
res = max( res , (LL)width * s.top().h );
s.pop();
}
printf( "%lld\n" , res );
}
return 0;
}
0x12をキュー
キューは循環キュー空間手書きキューを最適化するために使用することができ、「FIFO」リニアデータ構造であり、
キューそのいくつかの変形例で、プライオリティキュー、キュー単調な、両端キュー、これらが存在する\(STLの\)正常キュー手書きの一部であるが、比較的大きな定数
また、プライオリティキューにもPBDのです
132チームのチームをAcWing
この質問自体が難しく、単にデータ処理がより嫌ではありません
まず、メンテナンスチームのためにキューを開き、開いた\(N \)各チームのメンバーを維持するためにキューを
要素に押し込まれるたびに、キューが空のグループは、キューの合計に彼を取っている場合の要素は、このグループのキューに参加入れます
たびにポップアップ要素は、グループHOLキューが空の場合、この時点では、隊がグループを並んで頭を入れ、キュー先頭グループが総から合計キューを取り出し置きます
この質問は非常に一定のカードではない、開けないでください\(O2 \)を生きることができ、一見、
また、良い習慣が誤ってヒット、キューをジャンプしません
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
const int N = 1e6 + 5 , M = 1005;
int n , t , m , num , cub[N];
string opt;
map< int , queue<int> > member;
queue< int > team;
inline int read()
{
register int x = 0;
register char ch = getchar();
while( ch < '0' || ch > '9' ) ch = getchar();
while( ch >= '0' && ch <= '9' )
{
x = ( x << 1 ) + ( x << 3 ) + ch - '0';
ch = getchar();
}
return x;
}
inline void push()
{
num = read();
if( member[ cub[num] ].empty() ) team.push( cub[num] );
member[ cub[num] ].push( num );
return ;
}
inline void pop()
{
num = team.front();
printf( "%d\n" , member[ num ].front() );
member[ num ].pop();
if( member[ num ].empty() ) team.pop();
}
inline void work( int k )
{
n = read();
if( !n ) exit(0);
printf( "Scenario #%d\n" , k );
while( !team.empty() )
{
num = team.front();
while( !member[ num ].empty() ) member[ num ].pop();
team.pop();
}
memset( cub , 0 , sizeof(cub) );
for( register int i = 1 ; i <= n ; i ++ )
{
t = read();
while( t -- ) cub[ read() ] = i;
}
while( 1 )
{
cin >> opt;
if( opt == "ENQUEUE" ) push();
else if( opt == "DEQUEUE" ) pop();
else break;
}
puts("");
return ;
}
int main()
{
for( register int k = 1 ; 1 ; k ++ ) work(k);
return 0;
}
135最大のサブシーケンスをAcWingし、
モノトーン操作キューグループ
通常の状況および問題の下の最初のセクションでは、接頭転送およびアレイ乗算されるため、それが違いを生むことができ
そして、問題は、エンドポイントについて見つけることです
だから、接頭辞と配列です\(S \)
すでに列挙右ポイント\(私は\)と現在の左ポイント\(jは\)
その時間のいずれかで(K \)\条件場合\(K <J <私は\ ) と\(S [K]> Sは、[J] \) 、\(K \)は、いかなる場合においても最もになることができませんなぜならすべてのためのソリューション、\(私は\)であれば、オプション\(J \)その後、\(J \)定数\(K \) 、より好ましくは
だから我々は単調に増加するシーケンスを維持する必要性を見つけ、と\(私は\)にシフトしている、の一部が存在します\(j個\)は使用できません
単調キューでそれを維持するためにキューに対応する単調特性は、待ち行列要素が格納され、配列添字プレフィックスは、ヘッドは-する(Lの\)\、テールする\(R&LTの\)
それぞれの列挙のために\(私は\)以下の操作を持っています
- 場合\(Q [L] <I - Mの\は) のヘッドを強制的に
- この時、\(リットル\)があり、いくつかの最も\(j個\)の答えを更新
- メンテナンスモノトーン自然とキュー\(私は\)キューで
#include <bits/stdc++.h>
using namespace std;
const int N = 300000;
int n , m , s[N] , q[N] , l = 1 , r = 1 , res ;
inline int read()
{
register int x = 0 , f = 1;
register char ch = getchar();
while( ch < '0' || ch > '9' )
{
if( ch == '-' ) f = -1;
ch = getchar();
}
while( ch >= '0' && ch <= '9' )
{
x = ( x << 3 ) + ( x << 1 ) + ch - '0';
ch = getchar();
}
return x * f;
}
int main()
{
n = read() , m = read();
for( register int i = 1 ; i <= n ; i ++ ) s[i] = s[i-1] + read();
for( register int i = 1 ; i <= n ; i ++ )
{
while( l <= r && q[l] < i - m ) l ++;
res = max( res , s[i] - s[ q[l] ] );
while( l <= r && s[ q[r] ] >= s[i] ) r --;
q[ ++ r ] = i;
}
cout << res << endl;
return 0;
}