문제에 AtCoder 그랜드 대회 019 솔루션

\(에이\)

뻐꾸기

int a,b,c,d,n,t;
int main(){
    scanf("%d%d%d%d%d",&a,&b,&c,&d,&n);
    t=n&1,n-=t,a*=8,b*=4,c*=2;
    printf("%lld\n",1ll*min(min(a,b),min(c,d))*(n>>1)+(min(min(a,b),c)>>1)*t);
    return 0;
}

\(비\)

동일한 연산 결과를 고려하지 발견 롤오버 간격 경우 \ ([L, R] \ ) 를 만족 \ (S [1] =에서 S [R] \) 우리 이제 선택 동작 \ ([L + 1 R-1] \) 최종 시퀀스와 반전되도록 \ ([L, R이] \ ) 다음의 순서와 동일하다, 우리는 포함되지 않는다 ([L, R] \ \ ) , 우리는 단지 수를 카운트 위한 \ ([L, R] \ ) 를 만족 \ (S [L] \\ NEQ S [R & LT] \) , 최종 답변 \ (+ \ 1)

typedef long long ll;
const int N=2e5+5;
char s[N];int cnt[26],n,sum;ll res;
int main(){
    scanf("%s",s+1),n=strlen(s+1);
    fp(i,1,n)res+=sum-cnt[s[i]-'a'],++cnt[s[i]-'a'],++sum;
    printf("%lld\n",res+1);
    return 0;
}

\(씨\)

매트릭스 지적하고하기 위해, 소형 ~ 대형의 종축을 누를에 직접 (X \) \ , 상승 시퀀스를 구성하는 경우, 길이 \ (K <분 (X_2 - X_1, y_2 - y_1) +을 1 \) , 당신은 구석 수 있습니다 \ (케이 \) 감소, 시간을 \을 ((20-5 \ PI) 케이 \)

그렇지 않으면, 단지 코너 \ (K-1 \) 배 감소하고, 반원 걸어 \ ((20-5 \ PI) ( K-1) \) 더하기 (\ (10 \ PI -20) \)

//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=2e5+5;const double Pi=acos(-1.0);
int x[N],y[N],id[N],f[N],num[N];
int n,tot,cnt;
inline bool cmp(const int &a,const int &b){return y[a]<y[b];}
int main(){
    int x1,y1,x2,y2;
    scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&n);
    fp(i,1,n)scanf("%d%d",&x[i],&y[i]);
    if(x1>x2)swap(x1,x2),swap(y1,y2);
    if(y1>y2){
        swap(y1,y2);
        fp(i,1,n)y[i]=y1+y2-y[i];
    }
    fp(i,1,n)id[i]=i;
    sort(id+1,id+1+n,cmp);
    fp(i,1,n){
        R int u=id[i];
        if(y[u]>=y1&&y[u]<=y2&&x[u]>=x1&&x[u]<=x2)
            num[++tot]=x[u];
    }
    cnt=0,f[cnt]=-1;
    fp(i,1,tot){
        if(num[i]>f[cnt])f[++cnt]=num[i];
        else{
            R int k=lower_bound(f+1,f+1+cnt,num[i])-f;
            f[k]=num[i];
        }
    }
    R double res;
    if(cnt<min(x2-x1,y2-y1)+1)
        res=100.0*(x2-x1+y2-y1)-(20-Pi*5)*cnt;
    else res=100.0*(x2-x1+y2-y1)-(20-Pi*5)*(cnt-1)+(10*Pi-20);
    printf("%.12lf\n",res);
    return 0;
}

\(디\)

먼저 열거 된 \ (A \) 점에서 최종 위치 (B_1 \) \ 매치, 각 위치에 대하여 상기 범위의 최종 위치는, 다음의 공정에서 발생할 것인지 여부를 판단하는 경우 (\ 1 \) 그렇다면, 그것은 어디 될 수 있습니다

그렇지 않으면, 우리는 왼쪽에 도달 할 수없는 각각의 추가 포인트 찾기 \ (/ \) 당신이 왼쪽으로 멀리 가서 왼쪽으로 할 경우, 최소 거리의 권리 운동 후 나머지는 먼 왼쪽 그렇지 않으면 왼쪽으로 갈 수 당신은 오른쪽으로 이동해야합니다. 마찬가지로 지금까지 동일 시간

전체 복잡도 \ (O (N ^ 2 \ 로그 N) \)

//quming
#include<bits/stdc++.h>
#define R register
#define fi first
#define se second
#define pb emplace_back
#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 pair<int,int> pi;
const int N=2005,inf=0x3f3f3f3f;
char s[N*3],s1[N];
int sum[N*3],nl[N*3],nr[N*3],res,len;
vector<pi>vc;
void init(){
    nl[0]=-inf;
    fp(i,1,len*3)nl[i]=(s[i]=='1'?i:nl[i-1]);
    nr[len*3+1]=inf;
    fd(i,len*3,1)nr[i]=(s[i]=='1'?i:nr[i+1]);
    fp(i,1,len*3)sum[i]=sum[i-1]+(s[i]=='1');
}
inline int findl(R int x){return min(inf,x-nl[x]);}
inline int findr(R int x){return min(inf,nr[x]-x);}
int main(){
    scanf("%s%s",s1+1,s+1),res=inf;
    len=strlen(s+1);
    fp(i,len+1,len*3)s[i]=s[i-len];
    init();
    fp(i,1,len*2+1){
        vc.clear();
        R int c=0;
        fp(j,1,len)if(s1[j]!=s[i+j-1]){
            ++c;
            R int r=j+len,l=j+i-1;
            if(l>r)swap(l,r);
            if(sum[r]-sum[l-1]==0)
            vc.pb(pi(findl(l),findr(r)));
        }
        vc.pb(pi(0,0));
        sort(vc.begin(),vc.end());
        reverse(vc.begin(),vc.end());
        R int tmp=inf,mx=0;
        for(auto p:vc){
            if(p.fi!=inf&&mx!=inf)cmin(tmp,mx*2+p.fi*2);
            cmax(mx,p.se);
            if(mx==inf)break;
        }
        if(tmp!=inf)cmin(res,tmp+abs(len+1-i)+c);
    }
    if(res==inf)res=-1;
    printf("%d\n",res);
    return 0;
}

\(이자형\)

이모탈 무엇 아 이러한 방법을 생각 ......

유용한 제 위치에 두 개의 풀 \ (1 \) 또는 \ (1 \) \ (0 \) 전체의 편의 \ (1 \)의 중간 점하는 표시 \을 (1 \) \ (0 \) 왼쪽 포인트, 표시 \ (0 \) \ (1 \) 적절한 시점을 할 마음을. 라고도 중간 점의 개수 \ (A \) , 좌우 지점의 수는 점이다 \ (B \)

첫 매치하고는 A의 순서를 고려 (A_I, b_i) \ (\ ) 매치는 \ (A_I \)은 하기 (b_i \) \ 일측에 접속을 한 후 최종 도면 링 플러스 체인의 여러 조각의 개수가 확실히 상기 링의 중간 지점이고, 시작 및 종료 포인트 주위 체인 각각은 중간의 중간 지점이다. 링은, 동작의 상기 시퀀스 중은 체인에 작업 순서를 수정해야

SOL1

세트 \ ([I]은 [J f를 ] \) 나타내는 \ (J \) 로 중간 점 \ (나는 \) 프로그램 체인의 수, \ ([I] [J F = \ 합 _ {K \는 GEQ 0} {F는 [I-이. 1] [JK] 위에 \ (K +이. 1)!} \) , 분모 체인 나타내는 \을 (K + 1 \) 고정 된 에지의 순서는 최종 응답은 \ (A!의 B! (A + B)! \ sum_ {I = 0} ^ A ~ F [B]는 [I]는 \) 여기서 \은 ((A + B)는! \) 에지 쉽게 배치 나타내고, (\ ! \)\ (B! \) 가 두 개의 기준점 사이 나타낸다

우리는 다음 다항식 곱하여 각각 전달 등가 \는 (\ sum_ {I는 GEQ 0 \} {. 1 \ 위에 (I는 +. 1)!} X ^ I \) 라인에서, 그 다항식 급격한 전력의 복잡성 \ (O ) \ (N 로그 n \)

sol2

또 다른 방법이 제공된다 ([I] [J f를 \ ] \)은 총 넣어 나타내고 \ (I는 \) 의 중간 점 (\ J \) 번째 왼쪽 가리킨

\ [\ 시작 {정렬} F [I] [J] = 난 \ 시간 j 개의 \ 시간 F [I-1] [J] + F J ^ 2 \ 시간 [I] [J-1] \ 단부 {정렬} \]

전면 삽입은 부호, 즉 용이하게 교환 할 수 있고, 그렇게하기 전에 라벨에 의한, 중간 지점이다 \ (I는 \) , 다음 중 어느 하나는 체인의이면에 삽입 될 수 있도록하는 별 \ (J \)

후자는 새로운 왼쪽 지점을 삽입하므로, 어떠한 공감 라벨 걸릴 것입니다 \ (J의 \)를 , 그리고 당신이 그렇게 다음 오른쪽 지점 중 하나를 선택할 수 있기 때문에에 의해 \ (J의 \)

복잡성 \ (O (N ^ 2) \) 이미 경과

그러나 그것은 또한 다항식 최적화 설계 될 수있다 \ (g [I] [J] = {F [I] [J] \ 위에 (J!) ^ 2 (I!)} \) , 거기 \ (g [I] [J] = g [I] [J-1] + J \ 시간의 g [I-1] [J] \)

원래는 왼쪽에서 시작하는 오른쪽 하단 그리드로 볼 수있다, 곱한 각에 내려 가서 \ (IJ의 \) , 즉시에있어 \ (\ J ^ 2) , 모든 경로 가중 추구 로 \ (g [I] [J ] \) 만이 이후에 걸릴 내려가 \ (j의 \)

그런 다음 우리는 첫 번째 열거 \ (내가 \) 열은 첫번째 발견, 몇 가지 조치를 취했다 (내가 \) \를 열이 발생 \ ({1 \ 이상 1-IX} \) , 대답이 생성 함수의 모든 컬럼입니다 제품 직접 파티션 \ (NTT + \) 역 복잡도 다항식 \ (O (N ^ 기록 \ \), 2 N)을

그래서 게으른는 쓰기 때문에 \ (O (N ^ 2) \) 의

//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=998244353;
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=10005;
char s[N],t[N];int fac[N],ifac[N],f[N][N],n,cnta,cntb;
inline int C(R int n,R int m){return m>n?0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
inline void init(int n=10000){
    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);
}
int main(){
    init();
    scanf("%s%s",s+1,t+1),n=strlen(s+1);
    fp(i,1,n){
        cnta+=(s[i]=='1'&&t[i]=='1');
        cntb+=(s[i]=='1'&&t[i]=='0');
    }
    f[0][0]=1;
    fp(j,1,cntb)f[0][j]=mul(fac[j],fac[j]);
    fp(i,1,cnta)fp(j,1,cntb)
        f[i][j]=(1ll*i*j%P*f[i-1][j]+1ll*j*j%P*f[i][j-1])%P;
    R int res=0;
    fp(i,0,cnta){
        R int j=cnta-i;
        upd(res,1ll*f[i][cntb]*fac[j]%P*fac[j]%P*C(cnta,j)%P*C(cnta+cntb,j)%P);
    }
    printf("%d\n",res);
    return 0;
}

\(에프\)

좋은의 ......

첫째, 남아 있다고 가정 \ (n \) \ (\ 예)\ (m의 \) \ (없음 \) , 다음 대답은 확실히 더 많은 선택되는 같은 일 경우 단지 마스크

그리고 우리는 그 하나의 대답은에서 계획하는 것과 동일 좌표계로이 일을 넣어 \ (\ (N, m) ) 출발하는 () \ (0,0) \ , 경우 \ (Y = X \ ) 두 부분으로 좌표계,이 라인은 기여를 다음 왼쪽으로 갈 것이다, 기여는 위에서 아래로 이동합니다

가정 (제 n-m = \) \ , 처리는 대각선 위 또는 기여도가있는 거리 이하로 상관없이 발생하지 않는다 이동 (n \) \

그렇지 않으면, 가정 \합니다 (N- \의 GEQ의 m의 \) , 우리는 먼저 왼쪽으로 갈 것이다, 대각선 전에 이동 \ (nm의 \) 단계를, 대각선, 우리는 각각의 대각선을 만났다 여러 부분으로 나누어 경로 원은, 각 부분의 기여 기여의 대각선을 가로 질러 오지 않았다 전에 말했듯이되어, 총 기여해야 합니다 (N- \) \ 때, 같은 방식으로 \ (m \의 GEQ n을 \) 기여를해야 할 때 \ (m의 \)

그런 다음 대각선 점에 관계없이 방식의 모든의 기여 켜 \ ({2 이상 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;
const int P=998244353;
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=1e6+5;
int fac[N],ifac[N],n,m,res;
inline int C(R int n,R int m){return m>n?0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
inline int calc(R int n,R int m){return C(n+m,n);}
inline void init(int n=1e6){
    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);
}
int main(){
    init();
    scanf("%d%d",&n,&m);
    fp(i,1,min(n,m))upd(res,mul(calc(i,i),calc(n-i,m-i)));
    res=mul(res,ksm(mul(calc(n,m),2),P-2));
    upd(res,max(n,m));
    printf("%d\n",res);
    return 0;
}

추천

출처www.cnblogs.com/yuanquming/p/11600267.html