10.28 牛客提高集训营7

目录

  • 2018.10.28 牛客提高集训营7
    • A 中国式家长2(模拟)
    • B 随机生成树(贪心)
    • C 洞穴(倍增Floyd/bitset)

2018.10.28 牛客提高集训营7

期望得分:100+100+100
实际得分:100+100+100(0)

好不容易良心场,但是。。。
10.28 牛客提高集训营7_第1张图片
跑得快了,但是分没了。
预处理写错了,为什么上面两个还能过对拍啊==

比赛链接

A 中国式家长2(模拟)

题目链接

#include 
#include 
#include 
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define Fail puts("-1 -1")
typedef long long LL;
const int N=207;

int A[N][N];
bool ok[N][N],vis[N][N];
char IN[MAXIN],*SS=IN,*TT=IN;

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}
inline void Expand(int x,int y)
{
    ok[x-1][y-1]=ok[x-1][y]=ok[x-1][y+1]=1, ok[x][y-1]=ok[x][y+1]=1, ok[x+1][y-1]=ok[x+1][y]=ok[x+1][y+1]=1;
}

int main()
{
    int n=read(),m=read(),K=read();
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j) A[i][j]=read();
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j) ok[i][j]=read();
    vis[0][0]=vis[n+1][m+1]=1;
    for(int i=1; i<=n; ++i) vis[i][0]=vis[i][m+1]=1;
    for(int i=1; i<=m; ++i) vis[0][i]=vis[n+1][i]=1;

    int T=read(),now=K,get=0;
    for(int x,y; T--; )
    {
        x=read(),y=read();
        if(!ok[x][y]||vis[x][y]) {Fail; return 0;}
        if(A[x][y]<=0&&now<10) {Fail; return 0;}
        if(A[x][y]>0) now+=A[x][y], now>K&&(now=K);
        else now-=10, get+=10;
        vis[x][y]=1, Expand(x,y);
    }
    printf("%d %d\n",now,get);

    return 0;
}

B 随机生成树(贪心)

题目链接

//不用建树的。。确定fa的时候判下颜色就好了。
#include 
#include 
#include 
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=5e5+5;

int Enum,H[N],nxt[N<<1],to[N<<1],col[N],fa[N],Ans;
char IN[MAXIN],*SS=IN,*TT=IN;

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
#define AE(u,v) to[++Enum]=v,nxt[Enum]=H[u],H[u]=Enum
void Init(int n)
{
    for(int i=1; i<=n; ++i)
        for(int j=i+i,ci=col[i]; j<=n; j+=i)
            if(ci!=col[j]&&!fa[j]) fa[j]=i;
    for(int i=n; i; --i)
        for(int j=i+i; j<=n; j+=i)
            if(!fa[j]) fa[j]=i;
    for(int i=2; i<=n; ++i) AE(fa[i],i);
}
void DFS(int x,int c)
{
    if(c!=col[x]) c=col[x], ++Ans;
    for(int i=H[x]; i; i=nxt[i]) DFS(to[i],c);
}

int main()
{
//  freopen("B.in","r",stdin);
//  freopen(".out","w",stdout);

    int n=read();
    for(int i=1; i<=n; ++i) col[i]=read();
    Init(n);
    Ans=1, DFS(1,col[1]), printf("%d\n",Ans);

    return 0;
}

C 洞穴(倍增Floyd/bitset)

题目链接

倍增Floyd:

//147ms 620KB
//可以Floyd+倍增。然后就做完了。预处理是2的幂啊!
#include 
#include 
#include 
#include 
#define gc() getchar()
typedef long long LL;
const int N=101,M=1e4+5;

int n;
struct Matrix
{
    std::bitset A[N];
    inline void Init(int n)
    {
        for(int i=0; i>i&1) t=Mul(t,pw[i]);
    puts(t.A[u][v]?"YES":"NO");
}

int main()
{
//  freopen("C.in","r",stdin);
//  freopen("my.out","w",stdout);

    n=read();
    for(int m=read(); m--; S.A[read()-1].set(read()-1));
    pw[0]=S;
    for(int i=1; i<=29; ++i) pw[i]=Mul(pw[i-1],pw[i-1]);//not pw[i-1]*S...
    for(int Q=read(); Q--; Solve());

    return 0;
}

优化:

//8ms   492KB
//因为不需要关心任意两点的可达状态,只关心从u出发多少步能到哪些点。令f[i][j][k]表示走2^i步时j是否可以到k,就可以省去Floyd了。。
#include 
#include 
#include 
#include 
#define gc() getchar()
#define BIT 29
const int N=101;

std::bitset f[30][N];

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}

int main()
{
    int n=read();
    for(int m=read(),u; m--; u=read()-1,f[0][u].set(read()-1));

    for(int i=1; i<=BIT; ++i)
        for(int j=0; j ans,tmp;
        ans.set(u);
        for(int i=BIT; ~i; --i)
            if(k>>i&1)
            {
                tmp=ans, ans.reset();
                for(int j=0; j

转载于:https://www.cnblogs.com/SovietPower/p/9868537.html

你可能感兴趣的:(10.28 牛客提高集训营7)