문제에 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;
}

\(비\)

먼저 염색이 우리 앞에 다시 수행 전면 커버 뒤에 확실히하고, 각 지점 기록 \이 (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;
}

\(씨\)

긴 형성 최종 시퀀스하자 \을 (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;
}

\(디\)

첫째, 우리는 우리가 교환 할 수있는 경우 발견 \ (AB \)\ (교류 \) 경우, 당신은 교환의 다른 위치를 변경할 수 없습니다 \ (기원전 \)를 하나라도 있다면 우리 모두가 측면을 교환 할 수 있도록 한 후, 조작자의 내부와 직접 통신 블록에 대한 모든 포인트가 교체 위치에있는 통신 블록은 수있을 것이다

그런 다음 각 점에 대해, 심지어 측면을 고려 \ (U \) , 색상에 해당하는 최소 무게 설정 점 \ (MN \) 두 가지 경우가 있습니다 \ (U \) 에너지와 \ (MN \) 유니콤 사이드 직접 하나가 다른 색 찾을 그들의으로 접속된다 \ (V의 \)의 다음 에지 접속된다 \ ((U, V) \ ) 와 \ ((V, Mn)이 \) . 그래서 만약 \ (U \ NEQ 백만 \) 직접 측면, 심지어 측에 연결하거나 다른 색상을 찾을 수 있으며, 최소 무게 포인트로 \ (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;
}

\(에프\)

느낌 부문의 아들은 말처럼 \ (YYB의 \)가 나는 그것의 표현 장관의 아들에 대해 말할 여기에 좀 더 잘 이해 ......라고 ......

편리한 첫째 기본 \ (A_I = 내가 \)

첫째, 분명하다 \이 (내가 \ 당량 b_i \ 당량 2N-내가 \)

둘째, 우리는 두 개의 새로운 번호를 추가하는 것을 고려, 중간 값은 변경하거나 또는 전구체 또는 후계자가 될

그래서 두 가지 속성이있을 것

\ (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 \) 에 첨가 \ (I는 \)\ (2N-I \) 상기 선택된 제 2 속성을 설명하는 경우 \을 (B_i을 \) 다음 \ (S \) 의 모든 값에 \ (B_i \)\ (B_ {I + 1} \) (인해의 본성 (생략되어야 사이) 엔드 포인트를 제외한 숫자 \ (2 \) ) 숫자 앞에 명확하게 숫자의 존재하지 않는 것입니다

\ (PS : \) 제 점 위나 이해 될 수 있으며, 그 경우 \ (B_ {I} \ NEQ B_ {I + 1} \) 설명 \는 (B_가 {내가 + 1} \) 미리해야 (\ 2I + 1 \) 의 개수 (\ B_i \) 내의 부분의 다음 번호 선행 또는 후속들은 분명히 그들이 후속 또는 선행되고, 그래서 방지 \ (\) 없는

그런 다음 우리는 위의이 규칙에 따라 구성에 대해 생각하는 올 \ (ㄱ \) 엄격하게 합법적 인, 즉 \ (S \) 모든 숫자는 어떻게 자신의 충분 성을 증명하는 단지 필요성이있다

에서 \ (B_ {나는 + 1} \) 하기 (B_i \) \ 절차를, 경우 \ (B_. 1} + {I> B_i \) , 우리 삭제하기 전에 \ (2I를 + 1 \) 의 수 비율 \ (B_ {나는 + 1} \) 두 숫자의 큰 최소, 우리는 법적으로 얻을 수 있습니다 \ (b_i \) 최소 유사 경우 \ (B_ {나는 + 1} <b_i \) 최대 값과 걸릴 수 \을 (B_ {I} = B_ {난 + 1} \) , 그 다음, 우리가 삭제 직전 \을 (2I + 1 \) 수의 비율 (\ B_i \) 큰 최소 상기 비 \는 (b_i \) 보다 작은 최대 수의 최대 값과 최소값을 취할 수

다음 단계에서는 산출 방식 표시는 \ (F [I] [j는 [K] \) 역방향 고려 나타낸다 \ (B \) 고려 \ (I는 \) 다수의 유효한 값의 수 \ (J \) , 및 이러한 값의 첫 번째 걸릴 (케이 \) \ 다음 숫자가 줄에 처음 몇 법적 값을 취할 열거하는 전송 프로그램의 수를

실제로 문제가 기억 의 (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