12월 도전 2019 부문 1 题 解

나는 게임 인터페이스를 열었을 때 모든 문제는 혈액되었을 때 ......

BINXOR

가장 및 수를 가질 수 이상 직후 XOR 바이너리 \ (1 \) 계산이 범위에 열거 라인의 조합의 수를 계산. 참고 것을 \ (1 \) 번호는 \ (2 \) \ (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=1e9+7;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int inc(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;
char s[N];int cnt[2][2],fac[N],ifac[N],n,T,res,l,r;
inline void init(int n=2e5){
    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);
}
inline int C(R int n,R int m){return m<0||m>n?0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
int main(){
//  freopen("testdata.in","r",stdin);
    init();
    for(scanf("%d",&T);T;--T){
        scanf("%d",&n),cnt[0][0]=cnt[0][1]=cnt[1][0]=cnt[1][1]=0;
        scanf("%s",s+1);fp(i,1,n)++cnt[0][s[i]-'0'];
        scanf("%s",s+1);fp(i,1,n)++cnt[1][s[i]-'0'];
        l=n-min(cnt[0][0],cnt[1][0])-min(cnt[0][1],cnt[1][1]);
        r=min(cnt[0][0],cnt[1][1])+min(cnt[1][0],cnt[0][1]);
//      printf("%d %d\n",l,r);
        assert((r-l)&1^1);
        res=0;
        for(R int i=l;i<=r;i+=2)upd(res,C(n,i));
        printf("%d\n",res);
    }
    return 0;
}

CHFRAN

우선, 인 확실히 분할 선을 찾고 원래 문제는 다음 세그먼트로 우리 그래서 모든 턴 최선의 그룹의 그룹의 오른쪽 왼쪽 \ ([L, R-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 N=5e5+5;
int b[N],c[N],sf[N],fs[N],l[N],r[N],n,T,tot,res;
int main(){
//  freopen("testdata.in","r",stdin);
    for(scanf("%d",&T);T;--T){
        scanf("%d",&n),res=n+1,tot=0;
        fp(i,1,n){
            scanf("%d%d",&l[i],&r[i]),--r[i];
            b[++tot]=l[i],b[++tot]=r[i],b[++tot]=l[i]-1,b[++tot]=r[i]+1;
        }
        sort(b+1,b+1+tot),tot=unique(b+1,b+1+tot)-b-1;
        fp(i,0,tot+1)c[i]=sf[i]=fs[i]=0;
        fp(i,1,n){
            l[i]=lower_bound(b+1,b+1+tot,l[i])-b;
            r[i]=lower_bound(b+1,b+1+tot,r[i])-b;
            ++c[l[i]],--c[r[i]+1],++sf[r[i]],++fs[l[i]];
        }
        fp(i,1,tot+1)c[i]+=c[i-1],sf[i]+=sf[i-1];
        fd(i,tot,0)fs[i]+=fs[i+1];
        fp(i,1,tot)if(c[i]<n-1&&sf[i-1]>0&&fs[i+1]>0)cmin(res,c[i]);
        printf("%d\n",res==n+1?-1:res);
    }
    return 0;
} 

BINADD

뻗어 첫번째 문장 \ (B = 0 \) 의 경우는, 그 응답은 표 칠 발견 \ (A + B \) 진 긴 연속 이진수 \ (1 + \) 는 A (실시 예를 (\ 0 \) 비트 \ (B \)\ (0 \) 비트가 \ (1 \) 및 발 ) \ 1 (\\ (K \) 비트 \ (a \)\ (B \ ) 의 정확히 하나 \ (1 \) 다음 \ (A + B는 \) 연속 이진있을 것이다 \ (K + 1 \) 회)

증거의 법칙의 발견 후에는 그 넣어 진 추가를 실현하는 시간이기 때문에 그것은 단지 가장 긴 지속적으로 몇 번 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 N=1e5+5;
char s[N],t[N];int n,m,lim,res,cnt,T;
inline int max(R int x,R int y){return x>y?x:y;}
int main(){
//  freopen("testdata.in","r",stdin);
    for(scanf("%d",&T);T;--T){
        scanf("%s%s",s+1,t+1),n=strlen(s+1),m=strlen(t+1),lim=max(n,m);
        if(m==1&&t[m]=='0'){puts("0");continue;}
        reverse(s+1,s+1+n),reverse(t+1,t+1+m);
        fp(i,1,n)s[i]-='0';fp(i,n+1,lim)s[i]=0;
        fp(i,1,m)t[i]-='0';fp(i,m+1,lim)t[i]=0;
        res=0;
        fp(i,1,lim)if(s[i]&t[i]){
            cnt=1,++i;
            while(i<=lim&&(s[i]^t[i]))++i,++cnt;
            --i,cmax(res,cnt);
        }
        printf("%d\n",res+1);
    }
    return 0;
}

STICNOT

, 멸시 동생을 배울하지 않습니다 욕심

첫째, 우리는 에지 무게가 최대 연결에 해당하는 포인트가 모두보다 커야합니다 그가 어긋나는 부분과 모서리 및 무게를 찾을 수

우리는 여기에 하강 측을 첨가 그래서, 처음 두 지점 하부 우측의 경계 지점에 입사 에지에 의해 접속하면 (제 오른쪽 합성보다 크지 없을 수 있다는 다른 쪽)에 의해 식별 된 두 번째 측면에 부가 될 때 만 단지 시점의 하한 하한 판정 다른 시점 이후 판정하고 판정 되었기 때문에, 이는 최적에 연결되어 이들 두 지점 중 하나 (쉽게 찾을 확실히 아래 적은 이전) 하한 결정보다 길어야 바인딩. 다음 첫 번째, 두 지점은 측면을 필요 첨가에 대응하고, 각각의 다른 측면은, 나무 튜브를 형성하지 않아도, 직접 그리 될 수있는 것보다 큰 점을 필요로하거나 체중 같

//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;
int a[N],b[N],n,res,T;
int calc(){
    for(R int i=1,j=1;i<=n;++i){
        while(j<=n&&a[j]<b[i])++j;
        if(j>n)return n-i+1;
        ++j;
    }
    return 0;
}
int main(){
//  freopen("testdata.in","r",stdin);
    for(scanf("%d",&T);T;--T){
        scanf("%d",&n);
        for(R int i=1,u,v;i<n;++i)scanf("%d%d%d",&u,&v,&b[i]);
        fp(i,1,n)scanf("%d",&a[i]);
        sort(b+1,b+n),b[n]=b[n-1];
        sort(a+1,a+1+n);
        printf("%d\n",calc());
    }
    return 0;
}

BINOFEV

퇴폐 감

\ [\ 시작 {정렬} S & = \ sum_ {I = 0} ^ N \\ & = {1 \ 위에 R!} \ sum_ {I = 0} ^ n \ 좌측 (p {p는 R을 선택 \} ^ 난 \ 오른쪽) ^ {\ 밑줄 R} \ {단부 정렬} \]

그렇다면 우리 수 \ (X ^ {\ r은 밑줄 } \) 다음에 대해, 통상 다항식 변환 (X ^ I \) \ 전방 계수가 모두 백 동등한 것으로 (P ^ J \) \ 에 기하학적 시퀀스 가산이라고 우리가 계산 될 수있다

그러나, 나는 단지 것 \ (O (n \ 로그 ^ 2 N) \) 의 파티션 \ (NTT \) 연습 ...... 데이터 범위를 살펴이 걸린 이름이 ......

그런 다음 자신의 특정 수학 압연 배웠다

\ [{} 배향을 시작 \ 및 X는 ^ {\ 밑줄 = N} \ sum_k \ 시작 bmatrix {N} {\\ K} \ {단부 bmatrix} (- 1) ^ {NK X} ^ {K} \\ \ END] \ {} 배향

루오는 계곡에보고, 첫 번째 줄은 발견 할 수있는 클래스의 스털링 번호 \ (O (n \ 로그 N ) \) 찾을 여기

이 질문은 다음을 완료

//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 inc(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;
}
int kkk(R int x,R int y){
    R int res=1,d=1;
    for(;y;y>>=1,d=mul(d,x+1),x=mul(x,x))if(y&1)res=inc(mul(res,x),d);
    return res; 
}
const int N=(1<<20)+5;
int fac[N],ifac[N],lg[N],r[25][N],up[N],rt[2][N],inv[25];
int lim,d;
inline void swap(R int &x,R int &y){R int t=x;x=y,y=t;}
inline int C(R int n,R int m){return m>n?0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
void init(){
    fac[0]=ifac[0]=1;fp(i,1,1048576)fac[i]=mul(fac[i-1],i);
    ifac[1048576]=ksm(fac[1048576],P-2);fd(i,1048575,1)ifac[i]=mul(ifac[i+1],i+1);
    fp(d,1,20){
        fp(i,1,(1<<d)-1)r[d][i]=(r[d][i>>1]>>1)|((i&1)<<(d-1));
        inv[d]=ksm(1<<d,P-2),lg[1<<d]=d;
        fp(i,1<<(d-1),(1<<d)-1)up[i]=(1<<d);
    }
    for(R int t=(P-1)>>1,i=1,x,y;i<1048576;i<<=1,t>>=1){
        x=ksm(3,t),y=ksm(332748118,t),rt[0][i]=rt[1][i]=1;
        fp(k,1,i-1)
            rt[1][i+k]=mul(rt[1][i+k-1],x),
            rt[0][i+k]=mul(rt[0][i+k-1],y);
    }
}
void NTT(int *A,int ty){
    fp(i,0,lim-1)if(i<r[d][i])swap(A[i],A[r[d][i]]);
    R int t;
    for(R int mid=1;mid<lim;mid<<=1)
        for(R int j=0;j<lim;j+=(mid<<1))
            fp(k,0,mid-1)
                A[j+k+mid]=dec(A[j+k],t=mul(rt[ty][mid+k],A[j+k+mid])),
                A[j+k]=inc(A[j+k],t);
    if(!ty){
        t=inv[d];
        fp(i,0,lim-1)A[i]=mul(A[i],t);
    }
}
int f[N],n,T,m,p,res;
void solve(int *b,int len){
    if(!len)return b[0]=1,void();
    solve(b,len>>1);
    lim=up[len],d=lg[lim];
    int dm=(len>>1);
    static int A[N],B[N];
    for(R int i=0,c=1;i<=dm;++i,c=mul(c,dm))A[i]=mul(c,ifac[i]);
    fp(i,0,dm)B[dm-i]=mul(b[i],fac[i]);
    fp(i,dm+1,lim-1)A[i]=B[i]=0;
    NTT(A,1),NTT(B,1);
    fp(i,0,lim-1)A[i]=mul(A[i],B[i]);
    NTT(A,0);
    reverse(A,A+dm+1);
    fp(i,0,dm)A[i]=mul(A[i],ifac[i]);fp(i,dm+1,lim-1)A[i]=0;
    fp(i,0,dm)B[i]=b[i];fp(i,dm+1,lim-1)B[i]=0;
    NTT(A,1),NTT(B,1);
    fp(i,0,lim-1)A[i]=mul(A[i],B[i]);
    NTT(A,0);
    fp(i,0,len)b[i]=A[i];
    if(len&1){
        fd(i,len,1)b[i]=inc(mul(b[i],len-1),b[i-1]);
        b[0]=mul(b[0],len-1);
    }
}
int main(){
//  freopen("testdata.in","r",stdin);
    init();
    for(scanf("%d",&T);T;--T){
        scanf("%d%d%d",&n,&p,&m);
        fp(i,0,m)f[i]=0;
        solve(f,m);
        res=0;
        for(R int i=0,c=1;i<=m;++i,c=mul(c,p)){
            R int ret=mul(f[i],kkk(c,n));
            upd(res,(m-i)&1?P-ret:ret);
        }
        printf("%d\n",mul(res,ifac[m]));
    }
    return 0;
}

Offaihris

SB는 오랫동안 심지어 질문 카드입니다 ......

첫째, 계산 \ (점수 (I, J) \) 페어링 다음 다음 확실히 대량 주문에 대한 모든 작은 두 개의 10 진수, 그것은 최고의 단지 증거 인증서가 있어야합니다 그래서

다음 우리는 비트와 비트 사이의 기여는 독립적이라고 우리가 설정할 수있는 볼 (F_ {난, j는} \ \) 상승 부 나타낸다 \ (I \) 비트 \ (J \) 프로그램의 수, 그리고 각 2 회 (F_ {I, J} \ \) 와 (F_ {나, K} \ \) 라인에 업데이트 않음

그 다음에 계산 \ (F_ {I, J} \) , 우리가 할 수있는 직접 열거 \ (J \) 수 미만 \ (J \) 번호, 직접 \ (DP \) 라인에 구체적 코드를 살펴

//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 inc(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;
}
typedef long long ll;
ll l,r;int f[25][25],as[25][25],fac[25],ifac[25],inv[25];
int nd[25],sg[25],cnt[5],K,T,res;
void init(int n=20){
    fac[0]=ifac[0]=fac[1]=ifac[1]=inv[0]=inv[1]=1;
    fp(i,2,n){
        fac[i]=mul(fac[i-1],i);
        inv[i]=mul(P-P/i,inv[P%i]);
        ifac[i]=mul(ifac[i-1],inv[i]);
    }
    fp(i,0,9)fp(j,0,9)as[i][j]=abs(i-j);
}
inline int calc(R int a,R int b,R int c){
    return 1ll*fac[a+b+c]*ifac[a]%P*ifac[b]%P*ifac[c]%P*ksm(K,a)%P*ksm(9-K,c)%P;
}
void solve(int a,int b,int c,int op){
    if(K==0&&a||K==9&&c)return;
    cnt[0]=a,cnt[1]=b,cnt[2]=c;
    R int res=0;
    fd(i,20,1){
        fp(j,0,nd[i]-1)if(cnt[sg[j]]){
            --cnt[sg[j]];
            upd(res,calc(cnt[0],cnt[1],cnt[2]));
            ++cnt[sg[j]];
        }
        if(!cnt[sg[nd[i]]])break;
        --cnt[sg[nd[i]]];
        if(i==1)++res;
    }
    if(op==-1)res=inc(0,P-res);
    fp(i,a+1,a+b)upd(f[i][K],res);
}
int main(){
//  freopen("testdata.in","r",stdin);
    init();
    for(scanf("%d",&T);T;--T){
        scanf("%lld%lld",&l,&r),--l;
        res=0,memset(f,0,sizeof(f));
        fp(i,1,20)nd[i]=r%10,r/=10;
        fp(k,0,9){
            fp(i,0,k-1)sg[i]=0;fp(i,k+1,9)sg[i]=2;
            sg[k]=1,K=k;
            fp(i,0,19)fp(j,0,19-i)solve(i,20-i-j,j,1);
        }
        fp(i,1,20)nd[i]=l%10,l/=10;
        fp(k,0,9){
            fp(i,0,k-1)sg[i]=0;fp(i,k+1,9)sg[i]=2;
            sg[k]=1,K=k;
            fp(i,0,19)fp(j,0,19-i)solve(i,20-i-j,j,-1);
        }
        fp(i,1,20)fp(j,0,9)if(f[i][j])fp(k,j+1,9)if(f[i][k])
            upd(res,2ll*f[i][j]*f[i][k]%P*as[j][k]%P);
        printf("%d\n",res);
    }
    return 0;
}

추천

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