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

ポータル

この性能は、のようなものです\(ZZ \)

\(\)

直接最初の前に\(B \)総書かれたと\(1 \) 次いで元\(\)カラムライン否定

const int N=1005;
char mp[N][N];int n,m,a,b;
int main(){
    scanf("%d%d%d%d",&n,&m,&a,&b);
    fp(i,1,b)fp(j,1,m)mp[i][j]=1;
    fp(i,1,n)fp(j,1,a)mp[i][j]^=1;
    fp(i,1,n){
        fp(j,1,m)putchar(mp[i][j]+'0');
        putchar('\n');
    }
    return 0;
}

\(Bの\)

この場合のオーダーの最初のインターバルを除去し、次いで、操作\([I、iはK + \ -1]) と\([I + 1、I + K] \) 場合にのみ等価\(P_I \を)されている[I、iはK +(\ \)-1] 最小要素と\(P_ {I + K} )\ される([I + 1、iは\ \ Kを+]) 次に、最大の要素の計算されていない\(I + 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=2e5+5;
int a[N],st[N],up[N],dw[N],dr[N],top,n,res,k,fl;
int main(){
    scanf("%d%d",&n,&k);
    fp(i,1,n)scanf("%d",&a[i]);
    st[top=0]=0;
    fp(i,1,n){
        while(top&&a[i]>a[st[top]])--top;
        up[i]=(st[top]<=i-k),st[++top]=i;
    }
    st[top=0]=n+1;
    fd(i,n,1){
        while(top&&a[i]<a[st[top]])--top;
        dw[i]=(st[top]>=i+k),st[++top]=i;
    }
    for(R int l=1,r=2;r<=n;l=r++){
        while(r<=n&&a[r]>a[r-1])++r;
        fp(i,l+k-1,r-1)dr[i]=1;
    }
    fp(i,k,n)if(dr[i])fl=1;
        else if(!(up[i]&&dw[i-k]))++res;
    printf("%d\n",res+fl);
    return 0;
}

\(C \)

コンビニ提供

\ [\ {整列}開始回答&= \ sum_ {i = 1} ^ n個の\ sum_ {J = 1} ^ N \テキスト{LCM}(a_iを、a_j)\端{整列} \]

1マイナスライン上の最終的な答えマイナス

そして、退廃的な柿を開始

\ [\ {整列}開始回答&= \ sum_ {i = 1} ^ n個の\ sum_ {J = 1} ^ N \テキスト{LCM}(a_iを、a_j)\\&= \ sum_ {D = 1} ^ ND \ sum_ {i = 1} ^ n個の\ sum_ {J = 1} ^ N [D | a_iを] [D | a_j] {a_iを\ D上} {D上\ a_j} [\ GCD({a_iを\ D上}、{a_j \ Dオーバー})= 1] \\&= \ sum_ {D = 1} ^ ND \ sum_ {i = 1} ^ n個の\ sum_ {J = 1} ^ N [D | a_iを] [D | a_j] {a_iを\ D上} \ sum_ {T | {a_iを\ D}、T上| {a_j \ D上}} {\ D上a_j}ミュー\(T)\\&= \ sum_ {T =オーバー\ a_j {a_iを\ Tにわたって} {1} ^ n個の\ sum_ {D | T} D \ sum_ {i = 1} ^ n個の\ sum_ {J = 1} ^ N [T | | a_iを] [a_j T] T}ミュー(D上{T \})\\&= \ sum_ {T = 1} ^ N \ sum_ {i = 1} ^ n個の\ sum_ {J \ D ^ 2}倍以上{T ^ 2 \ \ T上\ a_j {a_iを\ Tにわたって} {} T \ sum_ {D = 1} ^ N [T | | a_iを] [a_j T] | T}、{T \ D上}ミュー\({T \ Dオーバー} )\\&= \ sum_ {T = 1} ^ n個の\ sum_ {I = 1} ^ n個の\ sum_ {J = 1} ^ N [T | a_iを] [T | a_j] {a_iを\ Tにわたって} {a_j \} Tを超えるT \ sum_ {D | T}のD \ミュー(D)\\ \端{整列} \]

最初の\(Oは(N Nログ\ )\) 前処理| \(T \ MU(D)\ S(T)= \ sum_ {D D}) 書き込み\(CNT [k]が\)を表し\を( a_iを= k個の\)番号、\ \(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 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,L=1e6;
bitset<N>vis;int p[N],mu[N],cnt[N],a[N],st[N],c[N],s[N],top,n,m,res;
void init(int n=L){
    mu[1]=1;
    fp(i,2,n){
        if(!vis[i])p[++m]=i,mu[i]=-1;
        for(R int j=1;j<=m&&i*p[j]<=n;++j){
            vis[i*p[j]]=1;
            if(i%p[j]==0)break;
            mu[i*p[j]]=-mu[i];
        }
    }
    fp(i,1,n)upd(mu[i],P);
    fp(i,1,n)for(R int j=i;j<=n;j+=i)upd(s[j],mul(i,mu[i]));
}
int main(){
//  freopen("testdata.in","r",stdin);
    scanf("%d",&n);
    init();
    fp(i,1,n)scanf("%d",&a[i]),++cnt[a[i]];
    fp(T,1,L){
        R int sum=0;
        for(R int j=T;j<=L;j+=T)upd(sum,mul(j/T,cnt[j]));
        sum=mul(sum,sum),sum=mul(sum,mul(T,s[T]));
        upd(res,sum);
    }
    fp(i,1,n)res=dec(res,a[i]);
    res=mul(res,(P+1)>>1);
    printf("%d\n",res);
    return 0;
}

\(D \)

最初の\(M = N-1 \ ) ケース決意オフ文献は、のみ考える(m個の\ GEQ N \)\

新しいマップ構築\(G \)すべてについて、\(C_I = 0 \)の関係\を((B)\ ) として\(B \)そのような収縮終了点を有する同一の通信ブロックの後それぞれについて\(C_I = 1 \)の関係\((B)\ ) 満足しなければならない\(B \) または異なる通信ブロックでない溶液

通信ブロックの数と呼ばれる\(K \) 我々は、各通信ポイントから全ての分析を、ブロックを削除する場合、リング状に接続された点、も容易スパニングツリー各通信ブロックので、トータル辺の数\(N- \) 少なくとも二つの異なるブロック間の任意の通信が指すことを保証することができる(2 \)\下縁の数の結合、及び前のように、我々がいることを確認しているパス、\(M \ GEQのn \)は、下限に到達できる必要があります

通信にまたがる各ブロック内で、再び上限を検討し、選択した点の間も完全グラフ、辺の数であり、{K、N-K +(\ 2上\(K-1)} = N + {K(K- 3)\ 2オーバー} \) そして上限は確かに、より良い、より大きな、それは私たちは、直接使用余分なプラス側は必要ありませんと言うことです\(G \)を確実にするためにサイドを\(k個\)を最大

\(PS:\)接続ブロックの総数である\(1 \)または\(2 \)が議論する必要がない場合境界が境界上に配置されていると判定され

限り\({m個の\当量のn + 2上K(K-3)\} \) 溶液、または全く溶液を有します

//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;
const int N=1e5+5;
struct eg{int u,v,c;}e[N];
ll m,sum;int fa[N],n,q;
inline int find(R int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int main(){
    scanf("%d%lld%d",&n,&m,&q);
    fp(i,1,n)fa[i]=i;
    for(R int i=1,u,v;i<=q;++i){
        scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c);
        ++e[i].u,++e[i].v;
        if(!e[i].c)u=find(e[i].u),v=find(e[i].v),fa[u]=v;
        if(e[i].c&&m==n-1)return puts("No"),0;
    }
    if(m==n-1)return puts("Yes"),0;
    for(R int i=1,u,v;i<=q;++i)if(e[i].c){
        u=find(e[i].u),v=find(e[i].v);
        if(u==v)return puts("No"),0;
    }
    fp(i,1,n)sum+=(find(i)==i);
    sum=n-sum+(1ll*sum*(sum-1)>>1);
    puts(m<=sum?"Yes":"No");
    return 0;
}

\(E \)

まず、\(最小-最大\)変換ルック撥を収容するには、質問がために一組になる\(S \) 提供\(S = {T_L、T_2、..、T_mを} \) 前記第一\ (T_I \)出現回数に到達\(B_ {T_I} \)の所望のステップ数を

我々は、状態設定\を(X_1、X_2、...、x_m(X_I <T_I B_ {})\)を表し、\(T_I \)にだけ現れた\(X_I \)に設けられ、回\(P \)表現するために生成されましたセット内の数\(S \)確率は、工程状態変化の予想される数である\({P上1 \} \)の発生状態計算場合は、同じ時間の確率\(Pを\) 次いで、それ応答への寄与である\({P上のp \} \) 。すべての法的場合\(X \)が設定まで追加貢献計算することができる\(S \)最初の\(T_I \)到着発生\(B_ {T_Iを} \)場合、ステップ数の期待値をインクルード

以下のための\(P \)に設けられ、\(X- = \ sum_ {I ^ M} = T_I。1 \) そこ

\ [\開始{整列} P = X!\ sum_ {i = 1} ^ m個の\左({T_I \ P上} \右)^ {X_I} {X_I上1 \!} \端{整列} \]

次に、設定されたドロップができる([I]、[J F \ ] [k]が\) の考慮を表し\(Iは\)セットから選択された数、\(X-J = \)、\ (\ SUMを= k個の\)状態への最後の正当寄与の各々の総寄与のプラス

//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=405;
int fac[N],ifac[N],bin[N],f[N][N][N],a[N],b[N],n,s1,s2;
inline void init(R int n=400){
    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(){
//  freopen("testdata.in","r",stdin);
    scanf("%d",&n);
    init();
    fp(i,1,n)scanf("%d%d",&a[i],&b[i]);
    f[0][0][0]=P-1;
    fp(i,1,n){
        fp(j,0,s1)fp(k,0,s2)f[i][j][k]=f[i-1][j][k];
        bin[0]=1;fp(j,1,b[i]-1)bin[j]=mul(bin[j-1],a[i]);
        fp(j,0,b[i]-1)bin[j]=mul(bin[j],ifac[j]);
        fp(j,0,s1)fp(k,0,s2)fp(v,0,b[i]-1)
            upd(f[i][j+v][k+a[i]],P-mul(f[i-1][j][k],bin[v]));
        s1+=b[i]-1,s2+=a[i];
    }
    R int res=0;
    fp(i,0,s1)fp(j,1,s2){
        R int ret=mul(f[n][i][j],fac[i]);
        ret=mul(ret,ksm(j,P-1-i));
        upd(res,mul(ret,mul(s2,ksm(j,P-2))));
    }
    printf("%d\n",res);
    return 0;
}

\(F \)

まず、から\(私は\)にする(\ P_Iを)\でもエッジ、それは確かにリングの数だけ選択することができ、同時にリングの数、およびすべての形成である\(私は\)または\(P_I \) 私たちは覚えています同時に選択された(私は\)\\(1 \) 同時に選択\(P_I \)がされている(0 \)\

同様から\(Iは\)する(Q_I \)\接続されたエッジを、しかし群から選択される同じ時に参照(Iは\)\される(0 \)\同時に選択、\(Q_I \)\(1 \)

次いで、書き込み\(Xを[I] \)\(Y [i]が\)表現(私は\)\その後、リングする(Iは\)\かどうか、それが値を持つ二つのリングが配置されている貢献そして\(P_I \)及び(Q_I \)\値に応じて、関連する\(P_I \)及び(Q_I \)\値は、ライン上に議論します

問題の議論直接結合溶液を記述するのが面倒(ここで\(V_I \)は、対応するリングの値を表します)

これは、明らかに何かが最小カットモデルに変換することができます

//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)
#define gg(u) for(int &i=cur[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,M=1e6+5,inf=0x3f3f3f3f;
inline int min(R int x,R int y){return x<y?x:y;}
struct eg{int v,nx,w;}e[M];int head[N],tot=1;
inline void add(R int u,R int v,R int w){
    e[++tot]={v,head[u],w},head[u]=tot;
    e[++tot]={u,head[v],0},head[v]=tot;
}
int dep[N],cur[N],S,T,n;
bool bfs(){
    memset(dep,-1,(T+1)<<2);
    memcpy(cur,head,(T+1)<<2);
    static int q[N];
    int h=1,t=0,u;q[++t]=S,dep[S]=0;
    while(h<=t){
        u=q[h++];
        go(u)if(e[i].w&&dep[v]<0)q[++t]=v,dep[v]=dep[u]+1;
    }
    return ~dep[T];
}
int dfs(int u,int lim){
    if(u==T||!lim)return lim;
    int fl=0,f;
    gg(u)if(dep[v]==dep[u]+1&&(f=dfs(v,min(lim,e[i].w)))){
        fl+=f,lim-=f,e[i].w-=f,e[i^1].w+=f;
        if(!lim)break;
    }
    if(!fl)dep[u]=-1;
    return fl;
}
inline int dinic(){R int res=0;while(bfs())res+=dfs(S,inf);return res;}
int p[N],q[N],blp[N],blq[N],s0[N],s1[N],sum,cnt;
int main(){
//  freopen("testdata.in","r",stdin);
    scanf("%d",&n);
    fp(i,1,n)scanf("%d",&p[i]),++p[i];
    fp(i,1,n)scanf("%d",&q[i]),++q[i];
    fp(i,1,n)if(!blp[i]){
        ++cnt;
        for(R int j=i;!blp[j];j=p[j])blp[j]=cnt;
    }
    fp(i,1,n)if(!blq[i]){
        ++cnt;
        for(R int j=i;!blq[j];j=q[j])blq[j]=cnt;
    }
    S=0,T=cnt+1;
    fp(i,1,n)sum+=p[i]!=q[i];
    fp(i,1,n){
        if(p[i]==q[i]){
            if(p[i]==i)continue;sum+=2;
            add(S,blp[i],1),add(blq[i],T,1),add(blp[i],blq[i],2);
        }else{
            if(p[i]==i)add(S,blq[i],1);
            else if(q[i]==i)add(blp[i],T,1);
            else add(blp[i],blq[i],1);
        }
    }
    printf("%d\n",sum-dinic());
    return 0;
}

おすすめ

転載: www.cnblogs.com/yuanquming/p/11565870.html
おすすめ