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

ポータル

\(\)

彼は直接転送を望んでいます

typedef long long ll;
const int N=55;
ll f[N][2];int a[N],n,p;
int main(){
    scanf("%d%d",&n,&p);
    fp(i,1,n)scanf("%d",&a[i]),a[i]&=1;
    f[0][0]=1;
    fp(i,1,n){
        f[i][0]=f[i-1][0],f[i][1]=f[i-1][1];
        if(a[i]&1)f[i][0]+=f[i-1][1],f[i][1]+=f[i-1][0];
            else f[i][0]+=f[i-1][0],f[i][1]+=f[i-1][1];
    }
    printf("%lld\n",f[n][p]);
    return 0;
}

\(Bの\)

私はよ\(ZZ \) ......

各数の寄与は、我々は、行の上限と下限の寄与の合計をカウント、いくつかの積極的な貢献を列挙正または負のいずれかであります

typedef long long ll;
int n,a,b,c,d;ll l,r;
int main(){
    scanf("%d%d%d%d%d",&n,&a,&b,&c,&d),b-=a;
    fp(i,0,n-1){
        l=1ll*i*c-1ll*(n-1-i)*d;
        r=1ll*i*d-1ll*(n-1-i)*c;
        if(b>=l&&b<=r)return puts("YES"),0;
    }
    puts("NO");
    return 0;
}

\(C \)

私の心は、それのペーストを充填している......

数の(iは\)\があれば、\(CNTは[i]が\)回、我々のように見ることができる\([I-CNT [I ] + 1、i]の\) セクションを追加する位置、それは多くの変更が必要である\(0 \)位置の数を、その後、修正ができる(\ O(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 cnt[N],vis[N],a[N],n,m,res;
inline void ins(R int x){++cnt[x];if(x-cnt[x]+1>=1&&!vis[x-cnt[x]+1]++)--res;}
inline void del(R int x){if(x-cnt[x]+1>=1&&!--vis[x-cnt[x]+1])++res;--cnt[x];}
int main(){
    scanf("%d%d",&n,&m),res=n;
    fp(i,1,n)scanf("%d",&a[i]),ins(a[i]);
    for(R int i=1,x,y;i<=m;++i){
        scanf("%d%d",&x,&y);
        del(a[x]),a[x]=y,ins(a[x]);
        printf("%d\n",res);
    }
    return 0;
}

\(D \)

問題の解決策の結果を確認するのに長い時間のように何の神々の結論を認めなかった......

私たちは、それらの各サブツリー考える\(SGの\)それは、その後、葉である場合は、値を\(SG(U)= 0 \) そうでない場合は、それぞれの息子は、サブゲームに相当し、息子のノード計算\を(V \)\ (SGの\)値の後、次いで、\(V \)サブツリープラス\((U、V)\ ) 、このエッジの\(SG \)の値である(SG(V)+1を\ \ )

さ削除証明、及び場合\((u、v)は\ ) 、このエッジは、次に\(SG = 0 \)は、そうでない場合は削除仮定がある\(V \) ツリーのサブツリー側得られた\(Vの\)元サブツリー\(T \)を得ることができます\(T '\) 我々は誘導を使用する場合は、\((Tは、SG')\ ) を引き継ぐことができます\( [0 + 1,1 + 1,2 + 1、...、SG(T)+。1 -1] \) そう\(SG(U)= SG (T)+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=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;}
int sg[N],n;
void dfs(int u,int fa){
    sg[u]=0;
    go(u)if(v!=fa)dfs(v,u),sg[u]^=sg[v]+1;
}
int main(){
    scanf("%d",&n);
    for(R int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
    dfs(1,0);
    puts(sg[1]?"Alice":"Bob");
    return 0;
}

\(E \)

各点のために\(Iは\) 場合\は(C_I = 0 \) 次いでせ\(L = a_iを\)そうでなければ配置された\(L = -c_i \) 場合\は(D_I = 0 \)次いでせ(\ R = -b_i \)そうでなければ、聞かせて\(R = D_I \) 我々は、もしことが判明\ \((LI、RI)が ) に接続することができる\((L、R)\ ) 右側の場合にのみ\(LI = R \)

そこで、((L、R)\ \ ) として\(Lの\)に接続されている\(R&LTの\)一つのエッジの後、これは今、各パスの開始時に正の数であるように、パスの数に分解しなければなりません、最後は否定的です。次いで明確度に等しいより大きい正の数、負度程度以上で、少なくとも点のうち度に等しくない(そうでないものは、分解を持たないリングと、各通信ブロックについて決して)パスの数に

//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=405;
int fa[N],vis[N],in[N],out[N],n,h;
inline int find(R int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int main(){
    scanf("%d%d",&n,&h);
    fp(i,0,h<<1)fa[i]=i;
    for(R int i=1,a,b,c,d,l,r;i<=n;++i){
        scanf("%d%d%d%d",&a,&b,&c,&d);
        l=(c?-c:a)+h,r=(d?d:-b)+h,fa[find(l)]=find(r);
        ++out[l],++in[r];
    }
    fp(i,-h,-1)if(out[i+h]>in[i+h])return puts("NO"),0;
    fp(i,1,h)if(in[i+h]>out[i+h])return puts("NO"),0;
    fp(i,0,h<<1)if(in[i]!=out[i])vis[find(i)]=1;
    fp(i,0,h<<1)if(in[i]&&out[i]&&!vis[find(i)])return puts("NO"),0;
    puts("YES");
    return 0;
}

\(F \)

それは激しい書き込むことができるように、まず、パスは、2進数に圧縮することができる\(O(2 ^ {2N })\) \(DP \)を

我々は接頭前であればいつでも場合にのみ、正当なパスを発見し、少ないとパスプレフィックスどのように最適化、考えてみましょう

今のセット考える\(私は\) フロント力パス、\(J-1 \) 1と同じ工程、のアカウント\(J \)ステップを

同じ直接の無視、または離れて前のステップの場合ならば\(1 \)これまでのところへ行くか\(0 \)明らかに\(GG \) あなただけ離れて、前のステップを検討する必要があります(1 \)\今のところへ行くか(0 \)\

我々は見つける\(I-1 \)の次の\(1 \)の位置、およびその置く\(1 \)の制限がまだ合法ですので、フロントに移動する位置を

次があれば\(1 \)その後、現在の道路は明らかに簡単に行くことができます

あまり直接的\(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 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=(1<<20)+5;
int f[25][N],g[N],is[25][25],nxt[N][25],n,m,k,res,lim;
int main(){
//  freopen("testdata.in","r",stdin);
    scanf("%d%d%d",&n,&m,&k),--n,lim=(1<<n);
    memset(is,-1,sizeof(is));
    for(R int i=1,a,b,c;i<=k;++i)scanf("%d%d%d",&a,&b,&c),is[a][b-1]=c;
    fp(s,0,lim-1){
        R int p=-1;
        fd(i,n-1,0){
            if(s>>i&1)p=i;
            nxt[s][i]=p;
        }
    }
    f[n][0]=1;
    fp(i,1,m){
        fp(j,0,lim-1)g[j]=f[n][j];
        memset(f,0,sizeof(f));
        fp(j,0,lim-1)f[0][j]=g[j];
        fp(j,0,n-1)fp(k,0,lim-1)if(f[j][k])
            fp(l,0,1){
                if(is[i][j]!=-1&&l!=is[i][j])continue;
                R int t=k>>j&1;
                if(l==0&&t==1)continue;
                if(l==t)upd(f[j+1][k],f[j][k]);
                else{
                    R int p=nxt[k][j];
                    if(p==-1)upd(f[j+1][k|(1<<j)],f[j][k]);
                    else upd(f[j+1][k^(1<<j)^(1<<p)],f[j][k]);
                }
            }
    }
    fp(i,0,lim-1)upd(res,f[n][i]);
    printf("%d\n",res);
    return 0;
}

おすすめ

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