CF Круглый 594 (Div1) (A ~ D) краткие пояснения
Базовая школа не может играть Cf ах. ,
Иван Дурак и теория вероятностей
За $ 1 \ раз п $ обстоятельства, небольшой толчок толчок формула оказалась в два раза порядковый номер акта Фибоначчи (поскольку первая позиция может быть 0, может быть 1, то есть в два раза, либо в два раза).
Рассмотрим первую строку, первая строка есть два случая:
- Если первая линия 01010 ... в шахматном порядке, то 0 можно рассматривать как начало цвета, можно рассматривать как начало цвета. Тогда ситуация становится ощетинившийся $ 1 \ раз п $ есть. Тогда рассмотрим положение 1x1 0 может быть 1, так что эта ситуация является число $ 2 F (N) $
- Другие случаи, первая строка $ 2f (м) - 2 $ случай, эти времена, так как первая линия соседней пары одного и те же, из того же самого начала, он найдет эту картину можно однозначно определить следующую строку, так что только определены эта матрица.
Таким образом, общее число случаев составляет $ 2f (п) + 2f (м) - 2 $
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#include<set>
using namespace std;
#define int long long
typedef long long ll;
#define MAXN 200006
#define MAXM 450
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define inf 0x3f3f3f3f
#define cmx( a , b ) a = max( a , b )
#define cmn( a , b ) a = min( a , b )
#define upd( a , b ) ( a = ( a + b ) % P )
#define P 1000000007
void read( signed& x ) {
scanf("%d",&x);
}
void read( ll& x ) {
scanf("%lld",&x);
}
int n , m , x0;
#define swap( a , b ) a=a^b,b=a^b,a=a^b
int f[MAXN];
signed main() {
f[0] = f[1] = 1;
cin >> n >> m;
for( int i = 2 ; i <= max( n , m ) ; ++ i ) f[i] = ( f[i - 1] + f[i - 2] ) % P;
cout << ( ( f[n] * 2 ) % P + ( f[m] * 2 ) % P - 2 + P ) % P << endl;
}
B. The World Is Просто программирование задач (Hard Version)
Во-первых, если число левых и правых скобок не то же самое, очевидно, puts("0")
В противном случае, мы будем иметь возможность получить циклический сдвиг является законным способом , чтобы сделать текущую последовательность скобок. В частности, фигурные скобки стек, то он должен быть )))(((
в форме. Это может смещаться в основе этого цикла.
Теперь, когда мы получили законную последовательность скобки. Если , (
как +1 , )
а -1, префиксы, и это не будет меньше 0, и определенный префикс и от 0 до 0. (Cf график вы можете увидеть официальные объяснения)
Тогда есть ответ в ряде легко веры вывода минимума возникают. Этот выводОчевидно установленоНа самом деле, рассмотреть вопрос о переходе к законному должны быть в квадратных скобках подстроки из передних, чтобы перейти к последней поверхности. Когда скобки первая последовательность переключения не является законным законным, а затем то же самое.
Название стало настолько упрощены, так что обмен двух скобок и минимальное количество префиксов как можно больше.
Два кронштейна обмена, если обмен передней )
и задней (
очевидно бесполезно ах!
Таким образом , он должен быть заменен в передней (
одной и задней )
, на этой последовательности префикса и отражается интервал -2
После выбора диапазона -2, он становится минимальным -2 / -1 / 0
- В минимум - 2. Что делать, если существует определенная -2 до 0, чтобы уменьшить -2, потому что оригинальный ответ номер 0, а теперь ответ на ряд -2. Даже лучше, он просто становится все 0 -2 нет значения.
- Минимальная становится --1. Так как минимальное значение становится -1 вместо -2, 0, конечно, не интервал. Мы следуем за все Сегменты последовательности 0, то мы не должны выбирать между интервалами два пролетами. Тем не менее, по-видимому, правомочно, если жадность уменьшить число как можно больше, конечно, отлично.
- Минимальное значение становится равным нулю. Во втором случае только 1 между ними. Тот же метод, чтобы делать только штрафом. Обратите внимание на то, что на самом деле не нужно, чтобы определить, есть ли период между 0, потому что разница, конечно, 1 или -1, так что этот раздел не обязательно лучше.
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#include<set>
using namespace std;
//#define int long long
typedef long long ll;
#define MAXN 600006
#define MAXM 450
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define inf 0x3f3f3f3f
#define cmx( a , b ) a = max( a , b )
#define cmn( a , b ) a = min( a , b )
#define upd( a , b ) ( a = ( a + b ) % P )
#define swap( a , b ) a = a ^ b , b = a ^ b , a = a ^ b
#define P 1000000007
void read( signed& x ) {
scanf("%d",&x);
}
void read( ll& x ) {
scanf("%lld",&x);
}
int n , p , x0;
char s[MAXN];
int S[MAXN];
stack<pair<int,char>> stk;
vector<int> x , y;
signed main() {
read( n );
scanf("%s",s + 1);
int cc = 0;
for( int i = 1 ; i <= n ; ++ i ) cc += ( s[i] == '(' ? 1 : -1 );
if( cc ) return puts("0\n1 1");
for( int i = 1 ; i <= n ; ++ i ) {
if( !stk.empty() && s[i] == ')' && stk.top().second == '(' ) stk.pop();
else stk.push( mp( i , s[i] ) );
}
int las = 1;
while( !stk.empty() && stk.top().se == '(' ) las = stk.top().fi , stk.pop();
-- las;
for( int i = 1 ; i <= n ; ++ i ) S[i] = S[i - 1] + (s[(i + las - 1 + n) % n + 1] == '(' ? 1 : -1);
int res0 = 0;
for( int i = 0 ; i <= n ; ++ i ) if( S[i] == 0 ) x.pb( i ) , ++ res0; else if( S[i] == 1 ) y.pb( i );
-- res0;
int ans = res0 , cur = 0;
pii ANS = mp(1 , 1);
for( int i = 0 ; i < x.size() - 1 ; ++ i ) {
cur = 0;
for( int j = x[i] + 1 ; j < x[i + 1] ; ++ j ) if( S[j] == 1 ) ++ cur;
if( cur > ans ) ans = cur , ANS = mp( x[i] + 1 , x[i + 1] );
ans = max( ans , cur );
}
for( int i = 0 ; i < y.size() - 1 ; ++ i ) {
cur = 0;
for( int j = y[i] + 1 ; j < y[i + 1] ; ++ j ) if( S[j] == 2 ) ++ cur;
if( cur + res0 > ans ) ans = cur + res0 , ANS = mp( y[i] + 1 , y[i + 1] );
}
cout << ans << endl;
ANS.fi += las - 1 , ANS.fi %= n , ANS.fi ++;
ANS.se += las - 1 , ANS.se %= n , ANS.se ++;
cout << ANS.fi << ' ' << ANS.se;
}
C Очередь в поезде
Решение проблемы, что моделирование наехало.
Решение этой проблемы зависит от него. , Он должен использовать три аналоговые набор выглядеть как
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define MAXN 100006
#define tup tuple<int,int,int>
int n , p;
int t[MAXN];
set<tup> evt;
set<int> want , que;
int qt = 0 , ct = 0 , ans[MAXN];
signed main() {
cin >> n >> p;
for( int i = 1 ; i <= n ; ++ i ) scanf("%lld",&t[i]) , evt.insert( make_tuple( t[i] , 0 , i ) );
while( !evt.empty() ) {
tup th = *( evt.begin() ); evt.erase( evt.begin() );
ct = get<0>(th);
if( !get<1>(th) )
want.insert( get<2>(th) );
else
que.erase( get<2>(th) ) , ans[get<2>(th)] = ct;
if( want.empty() ) continue;
if( que.empty() || *( want.begin() ) < *( que.begin() ) )
evt.insert( make_tuple( max( qt , ct ) + p , 1 , *(want.begin()) ) ) , qt = max( qt , ct ) + p , que.insert( *(want.begin()) ) , want.erase( want.begin() );
}
for( int i = 1 ; i <= n ; ++ i ) printf("%lld ",ans[i]);
}
D Catowice City
Потому что у меня есть левая сторона на правую сторону I, эквивалент говорит вам за $ я $ выбрать либо влево или правильный выбор.
Один слева u
подключен к правой v
стороне соответствует левый выбран определяет единственный выбор слева, эта ситуация может дать , чтобы даже направлено ребро указывает на то, если левый, также должны быть оставлены.u
v
u
v
u
v
Точка может затем быть уменьшена, чтобы найти проникновение SCC 0 устанавливаются справа, другие на праве, как.
Конечно, если есть только один SCC-видимому, не имеет решения.
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#include<set>
using namespace std;
//#define int long long
typedef long long ll;
#define MAXN 1000006
#define MAXM 450
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define inf 0x3f3f3f3f
#define cmx( a , b ) a = max( a , b )
#define cmn( a , b ) a = min( a , b )
#define upd( a , b ) ( a = ( a + b ) % P )
#define swap( a , b ) a = a ^ b , b = a ^ b , a = a ^ b
#define P 1000000007
void read( signed& x ) {
scanf("%d",&x);
}
void read( ll& x ) {
scanf("%lld",&x);
}
int n , m;
vector<int> G[MAXN]; int ind[MAXN];
int dfn[MAXN] , low[MAXN] , clo , ins[MAXN] , stk[MAXN] , tp = 0;
int indg[MAXN] , bl[MAXN] , scc; vector<int> sc[MAXN];
void tarjan( int u ) {
dfn[u] = low[u] = ++ clo , ins[u] = 1 , stk[++ tp] = u;
for( int v : G[u] ) {
if( !dfn[v] ) tarjan( v ) , low[u] = min( low[u] , low[v] );
else if( ins[v] ) low[u] = min( low[u] , dfn[v] );
}
if( dfn[u] == low[u] ) {
int x; ++ scc;
do {
x = stk[tp--] , bl[x] = scc , ins[x] = 0 , sc[scc].pb( x );
} while( x != u );
}
}
vector<int> ans1 , ans2;
int main() {
int t; cin >> t;
while( t-- ) {
read( n ) , read( m );
for( int i = 1 ; i <= n ; ++ i ) G[i].clear() , low[i] = dfn[i] = ins[i] = stk[i] = bl[i] = indg[i] = 0;
for( int i = 1 , u , v ; i <= m ; ++ i ) {
read( u ) , read( v );
G[u].pb( v );
}
for( int i = 1 ; i <= scc ; ++ i ) sc[i].clear();
scc = 0;
for( int i = 1 ; i <= n ; ++ i ) if( !dfn[i] ) tarjan( i );
for( int i = 1 ; i <= n ; ++ i )
for( int v : G[i] ) if( bl[v] != bl[i] )
++ indg[bl[v]];
if( scc == 1 ) { puts("NO"); continue; }
puts("YES");
int flg = 0;
ans1.clear() , ans2.clear();
for( int i = 1 ; i <= scc ; ++ i )
if( flg || indg[i] )
for( int v : sc[i] ) ans1.pb( v );
else { for( int v : sc[i] ) ans2.pb( v ); flg = 1; }
printf("%d %d\n",ans1.size() , ans2.size( ));
for( int v : ans1 ) printf("%d ",v); puts("");
for( int v : ans2 ) printf("%d ",v); puts("");
}
}