AtCoderグランドコンテスト問題の解決012

ポータル

\(\)

確かにフロントの後ろに2つずつが最適に同行します

typedef long long ll;
const int N=5e5+5;
int a[N],n;ll res;
int main(){
    scanf("%d",&n);
    fp(i,1,n*3)scanf("%d",&a[i]);
    sort(a+1,a+1+n*3);
    for(R int i=n+1;i<=n*3;i+=2)res+=a[i];
    printf("%lld\n",res);
    return 0;
}

\(Bの\)

最初の染色は、その後、我々は前に戻ってやる、フロントカバーの後ろに確かであり、各ポイントのレコード\は(D_I \) この時点からどのくらいを拡張することができ、場合にのみ、\(D_I \)は、それが考慮されたときに増加しますすべてので最初から、それを更新する\(dは\)が非常に小さいので、各点は以下で更新されていない\(D_I \)を合計複雑で、ある\(O(D_IN)\)

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int N=1e5+5;
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
struct node{int u,d,c;}E[N];
int d[N],c[N],q[N],n,m,Q;
void solve(int S,int dis,int col){
    int h=1,t=0,u;
    q[++t]=S;
    while(h<=t){
        u=q[h++];if(!c[u])c[u]=col;
        go(u)if(cmax(d[v],d[u]-1))q[++t]=v;
    }
}
int main(){
    scanf("%d%d",&n,&m);
    fp(i,1,n)d[i]=-1;
    for(R int i=1,u,v;i<=m;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
    scanf("%d",&Q);
    fp(i,1,Q)scanf("%d%d%d",&E[i].u,&E[i].d,&E[i].c);
    fd(i,Q,1)if(cmax(d[E[i].u],E[i].d))solve(E[i].u,E[i].d,E[i].c);
    fp(i,1,n)printf("%d\n",c[i]);
    return 0;
}

\(C \)

最終的なシーケンスとして長く形成してみましょう(P_1、P_2、P_3、\ ...、P_N、1,2,3、N \) 正当なシーケンスの数である見つけ、その後、フォーム(Pを\ \ )インクリメントされたシーケンス番号\( - 1 \)

その後、我々は(nは- ++ \)\、そして維持するために、同様のアイデアを掛けます。空集合のシーケンス番号がインクリメントされる見出さ\(1 \) 続いて\(N + 1 \)プロモーター配列番号\(\ 2倍\)が先行し、\(N + 1 \)シーケンス番号\(1 + \)

両端キューは、について十分に維持して

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
typedef long long ll;
deque<int>st;ll n,k;int pos;
int main(){
    scanf("%lld",&n);++n;
    while((1ll<<pos)<=n)++pos;
    fd(i,pos-2,0){
        st.push_back(++k);
        if(n>>i&1)st.push_front(++k);
    }
    printf("%d\n",k<<1);
    fp(i,0,k-1)printf("%d ",st[i]);
    fp(i,1,k)printf("%d ",i);
    return 0;
}

\(D \)

まず、我々は交換することができるかどうかことを見出した\(AB \)\(交流\)ケースを、あなたは交換で他の位置に変更することはできません\(紀元前\)を一つでもあれば、我々はすべての側面を入れ替えることができますので、その後、通信ブロックオペレータの内部とブロックの直接通信ができるようになりますため、すべての点が、交換位置であります

次いで、各点のために、偶数の側面を考える\(U \) 色に対応する最小量設定点\(MN \)、2例があり、\(U \)エネルギーと\(MN \)ユニコムその一つは、異なる色を見つけることであると側が直接、接続されている\(V \)を、次に接続されたエッジである\((U、V)\ ) と\((V、Mn)は\) もしそうであれば\(U \ NEQ MN \)と直接側と偶数側に接続された、または別の色を見つけることができ、それらの最小重量の点で\(V \)それ側に接続しよう。最終的にはすべての点の両側を接続し、同一の通信ブロック重量の最小点、その後ラインを計算するには余りにも困難で見出さ

//quming
#include<bits/stdc++.h>
#define R register
#define fi first
#define se second
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int P=1e9+7;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
    R int res=1;
    for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    return res;
}
const int N=2e5+5;
typedef pair<int,int> pi;
int fac[N],ifac[N],fa[N],mn[N],cnt[N];pi c[N];
int n,x,y,pos,sz,res;
inline int find(R int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int main(){
    scanf("%d%d%d",&n,&x,&y);
    fp(i,1,n)scanf("%d%d",&c[i].se,&c[i].fi);
    sort(c+1,c+1+n);
    pos=2;
    while(pos<=n&&c[pos].se==c[1].se)++pos;
    if(pos>n)return puts("1"),0;
    fd(i,n,1)mn[c[i].se]=i,fa[i]=i;
    fd(i,n,1){
        if(i!=mn[c[i].se]&&c[i].fi+c[mn[c[i].se]].fi<=x)
            fa[find(i)]=find(mn[c[i].se]);
        else if(c[i].se!=c[1].se&&c[i].fi+c[1].fi<=y)
            fa[find(i)]=find(1);
        else if(c[i].se!=c[pos].se&&c[i].fi+c[pos].fi<=y)
            fa[find(i)]=find(pos);
    }
    fac[0]=ifac[0]=1;fp(i,1,n)fac[i]=mul(fac[i-1],i);
    ifac[n]=ksm(fac[n],P-2);fd(i,n-1,1)ifac[i]=mul(ifac[i+1],i+1);
    fp(i,1,n)if(find(i)==find(1))++sz,++cnt[c[i].se];
    res=fac[sz];
    fp(i,1,n)res=mul(res,ifac[cnt[i]]);
    printf("%d\n",res);
    return 0;
}

\(F \)

部門の息子を感じることよりも、言った\(yybの\は)それの文言の長官の息子について言う私はここで少し良く理解して......と言う......

コンビニ最初のデフォルトの\(a_iを=私は\)

まず、それは明らかです\(I \当量b_i \当量 2N-iは、\)

第二に、我々は二つの新しい番号を追加することを検討し、中央値は変わらないか、前駆体または後継者になるのいずれかであります

だから、二つの性質があるだろう

\(1.I \当量b_i \当量2N-I \)

\(2 \)は、全く存在しない\(Iは、Jを\ <) そう\(b_j <b_i <B_ { J + 1} \) または\(> b_i> B_ b_j { J + 1} \)

私たちはそこに考えることができることを前提としてい\(Sは\)すべての合法的なことを示している(b_i \)\値のセットは、すべての最初にしなければならないが(N-B_Nは= \)\、その後、後方我々が構築した場合、\を(B \) および考慮\(B_i \)私たちが行くと自然の最初の代表\(S \)で追加されました\(私は\)\(2N-I \) 選択された第2の特性は説明場合は、\を(B_iを\) 次いで\(S \)のすべての値で\(B_i \)\(B_ {I + 1} \) (なぜならの性質の(省略されなければならないとの間に)エンドポイントを除く数\(2 \) の番号の前に明確な数字の存在ではないです

\(PS:\)二点以上または場合は、その理解することができる\(B_ {I} \ NEQ B_ {I + 1} \) 説明\(B_ {I + 1} \) 事前されなければならない(\を2I + 1 \)の数\(B_i \)先行または後続し、次にそれらの明らかにそれらが後継又は先行されることを防ぐ内のセクションの数、そう\(\)が存在しません

その後、我々は、上記のこのルールに従って構築された、について考えてみると、\(のb \)厳密に正当れ、その\(S \)すべての数字は、どのように彼らの十分性を証明するためにだけ必要があり、

\(B_ {I + 1} \) する(B_i \)\場合は、手順を\(B_ 1} + {I> B_i \)削除する前に、その後、我々\(2I + 1 \)の数を比\(B_ {I + 1} \) 2つの数の大きい最小、我々は合法的に取得することができ\(b_i \)最小、同様場合\(B_ {I + 1} <b_i \) 最大値と取ることができる\(B_ {I} = B_ {I + 1} \) 、その後、我々は削除直前に\を(2I + 1 \)数比\(B_i \)大きい最小数をそして比\(b_i \)より小さい最大数は、最大値と最小値を取ることができます

次のステップは、計算スキーム、示される(F [I] [J \ \] [K]) の逆考える表す\(B \) 考え\(Iは\)数の正当な値の数\ (J \) およびこれらの値の最初取る\(k個の\)の次数が行の最初の数に有効な値を取るものを列挙するために、転送、プログラムの数

実際に問題があるに注意してください(A \)\状況は同じであってもよいし、展開することができますプロパティは、状況に依存します

本当にまだ理解しやすいコードを見て......

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int P=1e9+7;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
    R int res=1;
    for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    return res;
}
const int N=105;
int a[N],f[N][N][N],n,res;
int main(){
    scanf("%d",&n);
    fp(i,1,n+n-1)scanf("%d",&a[i]);
    sort(a+1,a+n+n);
    f[1][1][1]=1;
    fp(i,1,n-1)fp(j,1,n+n-1)fp(k,1,j)if(f[i][j][k]){
        R int tj=j,tk=k;
        if(a[n+i]!=a[n+i-1])++tj;
        if(a[n-i]!=a[n-i+1])++tj,++tk;
        fp(h,1,tj){
            if(h<tk)upd(f[i+1][tj-(tk-h-1)][h],f[i][j][k]);
            if(h>tk)upd(f[i+1][tj-(h-tk-1)][tk+1],f[i][j][k]);
            if(h==tk)upd(f[i+1][tj][h],f[i][j][k]);
        }
    }
    fp(i,1,n+n-1)fp(j,1,i)upd(res,f[n][i][j]);
    printf("%d\n",res);
    return 0;
}

おすすめ

転載: www.cnblogs.com/yuanquming/p/11524460.html