2336 loj「JOI 2017決勝」绳

深刻

まず、すべての位置が最も色素に、一度により多くの時間を染めている、そして、最終的に染めた色のスタートが好きです。そして、あなたは、色素の欲望を開始することができません

この配列の後に染料をオフに仕上げることができる場合は、2の最終的な長さは、次に、2つだけの色の最初の最大は、最初と最後が偶数でなければならない大きなユニコムブロック長のためのすべての同じ色を満たすことであるがため長さが奇数であってもよいです

プルーフ、可能にするために、次に十分な条件、すなわち、このような特定の法律上の方法、時間以降の動作を考え出すことができる。次いで、ブロック長(この定数最適)に縮小最初の最後尾との通信、通信ので次いでブロック長が偶数であり、次の軸対称は裏返し、この操作は、カード2になるまで繰り返され、中間の長さが奇数法的ないしなければならないの長さを有すること。まず、最終奇数長さの中間にのみ減少場合、可能ですあなたが最後のターンではありません。奇数通信ブロック、より多く存在する場合、どのように中央部分が奇数の長さを持って回します。あなたはまだ尋ねることができます理解していない場合は、人を(TPQ)

次に答えが計算される考える。まず、ブロック長は、通信の偶数長の数に分割することが可能である\(2 \) 次いで、第1の長さに応じて、通信ブロック\(2 \)通信ブロックの位置を開始して(\を1 \)または\(2 \)分類議論、ならびに染色位置の最大値に相当する染色のような最小値、である。列挙2つのブロックがカラー通信している場合、回答に対応する各色をカウントしますその後、明らかに変化していない; 2は、その後、別の色を染めること色でない場合は、この色が考慮されていないものです。現在の色ではありません、現在の色は、あなたが現在の色を見つけることができない場合現在の色の損失を変更してはならない。今、私たちは、この色の位置を最大限に活用するために試してみたいものですが、一緒にいくつか列挙現在の位置や色があるかもしれない別の色を考慮し、これらの場所が離れて染めるためには、この色を貢献は、発生回数の合計である(\()\ CNTと呼ぶと現在の色のブロック内のブロックの同じ数( - )\(I {F_、J}と呼ぶ\) 色答えようになっている。\(私は\します)\(N-cnt_i- \ MAX_ { j個の\ NEQ I}(cnt_j-F_ {I、J})\)

、書き込み時\(F_ {I、Jを} \) エッジは、相互接続された異なる色のブロックの二色に入れることができる\(F_ {I、J} \) されている\(I、Jの\)の次に従い。辺の数との間の(cnt_j \)\別の色、及び場合列挙列挙下降\(F_ {I、J} = 0 \) \(J \)は列挙していません次は必ずしも優れていません

#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define db double

using namespace std;
const int N=1e6+10;
int rd()
{
    int x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
};
int n,m,a[N],cn[N],sq[N],an[N],f[N][2];
int v[N];
bool cmp(int aa,int bb){return cn[aa]>cn[bb];}
vector<int> e[N];
void wk()
{
    for(int i=1;i<=m;++i)
    {
        vector<int>::iterator it;
        for(it=e[i].begin();it!=e[i].end();++it)
            ++v[*it];
        for(int j=1;j<=m;++j)
        {
            int x=sq[j];
            if(i==x) continue;
            an[i]=max(an[i],cn[i]+cn[x]-v[x]);
            if(!v[x]) break;
        }
        for(it=e[i].begin();it!=e[i].end();++it)
            --v[*it];
    }
}

int main()
{
    n=rd(),m=rd();
    for(int i=1;i<=n;++i)
        a[i]=rd(),++cn[a[i]];
    for(int i=1;i<=m;++i)
        an[i]=cn[i],sq[i]=i;
    sort(sq+1,sq+m+1,cmp);
    for(int i=1;i+1<=n;i+=2)
        if(a[i]!=a[i+1])
            e[a[i]].push_back(a[i+1]),e[a[i+1]].push_back(a[i]);
    wk();
    for(int i=1;i<=m;++i) e[i].clear();
    for(int i=2;i+1<=n;i+=2)
        if(a[i]!=a[i+1])
            e[a[i]].push_back(a[i+1]),e[a[i+1]].push_back(a[i]);
    wk();
    for(int i=1;i<=m;++i) printf("%d\n",n-an[i]);
    return 0; 
}

おすすめ

転載: www.cnblogs.com/smyjr/p/11551169.html