AtCoder Grand Contest 019 solution to a problem

Portal

\(A\)

Cuckoo

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;
}

\(B\)

Not considered the same operation results, found that if a rollover interval \ ([l, r] \ ) satisfies \ (s [l] = s [r] \) then we can now select operation \ ([l + 1 , r-1] \) such that the final sequence and inverted \ ([l, r] \ ) is equal to the following sequence, then we do not count \ ([l, r] \ ) , so we only count the number for \ ([l, r] \ ) satisfies \ (S [L] \\ NEQ S [R & lt] \) , the final answer \ (1 + \) to

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;
}

\(C\)

Directly to the matrix points out, and then press the ordinate from small to large, in order to \ (X \) make up a rising sequence, if the length \ (k <min (x_2 - x_1, y_2 - y_1) + 1 \) , you can corner \ (k \) times, reduce \ ((20-5 \ pi) k \)

Otherwise, only the corner \ (k-1 \) times and then walk a semicircle, reducing \ ((20-5 \ pi) ( k-1) \) plus \ ((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;
}

\(D\)

First enumerate \ (A \) in that a final position and (B_1 \) \ match, then for each position and if the final position of the range, then judge whether it will encounter in the process \ (1 \) If yes, then it can become where

Otherwise, we find for each additional point can not be reached left \ (/ \) right movement of the minimum distance, if you make a left to go the furthest to the left, then the rest can also go to the left, otherwise the furthest left you must go to the right. Similarly times far is the same

Overall complexity \ (O (n ^ 2 \ log 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;
}

\(E\)

What are the immortals ah think of these methods ......

Useful first position only two, two full \ (1 \) or a \ (1 \) a \ (0 \) , the full convenience \ (1 \) denoted intermediate points, a \ (1 \) a \ (0 \) denoted the left point, a \ (0 \) a \ (1 \) in mind to do the right point. The number of the intermediate point referred to as \ (A \) , the number of left and right points are points \ (B \)

Our first match and then consider the order, for a \ ((a_i, b_i) \ ) match, the \ (a_i \) to \ (b_i \) connected to one side, then the final drawing is certainly a number of rings plus several pieces of chain , the ring is an intermediate point, the chain around the beginning and end points, respectively, the intermediate is an intermediate point. The ring, any of the above sequence of operations, to be fixed to the chain, the sequence of operations

sol1

Set \ (f [i] [j ] \) represents the \ (J \) intermediate point into \ (I \) the number of program chains, the \ (f [i] [j ] = \ sum _ {K \ GEQ 0} {F [I-. 1] [JK] \ over (K +. 1)!} \) , the denominator represents the chain \ (k + 1 \) sequence of edges fixed, the final answer is \ (A! B! (A + B)! \ sum_ {I = 0} ^ A F [B] [I] \) , where \ ((A + B)! \) represents the edge easily arranged, and \ ( A! \) and \ (B! \) there between represent two reference points

We then each transferred equivalent multiplied by a polynomial \ (\ sum_ {I \ GEQ 0} {. 1 \ over (I +. 1)!} X ^ I \) , then the polynomial rapid power on the line, the complexity of the \ (O (n \ log n) \)

sol2

Another method is provided \ (f [i] [j ] \) represents the total put \ (I \) intermediate points and \ (J \) th left point,

\[ \begin{aligned} f[i][j]=i\times j\times f[i-1][j]+j^2\times f[i][j-1] \end{aligned} \]

A front insertion is an intermediate point, that any reference numerals, i.e., can easily exchange and a label before, so by \ (I \) , then any one can be inserted in the back of the chain, so that by \ (J \)

The latter is to insert a new left point, so take any empathy label \ (j \) , and because you can choose any one of the right point so then by \ (j \)

Complexity \ (O (n ^ 2) \) already passed

But it may also be a polynomial optimization, design \ (g [i] [J] = {F [I] [J] \ over (J!) ^ 2 (I!)} \) , There \ (g [i] [j] = g [i] [j-1] + j \ times g [i-1] [j] \)

The original can be viewed as a grid on the bottom right to start from the left, go down on each multiplied by \ (ij \) , right away got on \ (J ^ 2 \) , all path weights and seek into \ (g [i] [j ] \) after that only to go down will take on \ (j \)

Then we enumerate the first \ (i \) column took a few steps, find the first \ (i \) generated column is \ ({1 \ over 1-ix} \) , the answer is all of the columns of the generating function product, directly partition \ (NTT + \) polynomial to the inverse complexity \ (O (n \ log ^ 2 n) \)

Because so lazy just write \ (O (n ^ 2) \) of

//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;
}

\(F\)

Good s ......

First, assume that there remain \ (n \) a \ (Yes \) and \ (m \) a \ (No \) , then the answer is certainly choose the more, if the same thing just a mask

Then we put this thing into a coordinate system, then the One answer is the equivalent of the scheme from the \ ((n, m) \ ) departure to \ ((0,0) \) , if \ (y = x \ ) the coordinate system into two parts, then this line will go to the left following contribution, contribution will go down in the above

Assume \ (the n-m = \) , and the process does not go diagonal encountered, no matter go above or below the walk contributions are \ (n \)

Otherwise, assume \ (the n-\ geq m \) , then go before the diagonal, we will first go to the left \ (nm \) step, if the diagonal, we met each diagonal the path circles divided into several parts, then the contribution of each part are said before did not come across the diagonal of the contribution, the total contribution must be \ (the n-\) , the same way when \ (m \ geq n \) when the contribution must be \ (m \)

Then the points on the diagonal, regardless of the way to turn the contribution of all \ ({1 \ over 2} \) , then we determine what passes for each point what is the probability it can be

//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;
}

Guess you like

Origin www.cnblogs.com/yuanquming/p/11600267.html