2018“百度之星”程序设计大赛 - 复赛

A 没有兄弟的舞会

直接按父亲分类,计算最大次大值

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector 
#define pi pair
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<' ';\
                        cout<#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}

void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (112345)
int T;
int f[MAXN][2]={};
int fa[MAXN];
set<int> e[MAXN];
ll v[MAXN];
int cmp(ll a,ll b){
    return a>b;
}
int main()
{
//  freopen("b.in","r",stdin);
//  freopen(".out","w",stdout);
    int T=read();
    while(T--) {
        int n=read();
        Fork(i,2,n) fa[i]=read();
        For(i,n) v[i]=read();
        fa[1]=0;
        For(i,n) e[fa[i]].p(v[i]);

        Rep(i,n+1) sort(ALL(e[i]),cmp);
        ll ans=0,ansp=0;
        Rep(i,n+1) {
            int sz=SI(e[i]);
            if(!sz) continue;
            if(sz>=1) {
                if(e[i][0]>0) ans+=e[i][0];
                if(sz>=2) gmax(ansp,(ll)e[i][1])
            }
        }
        printf("%I64d ",ans+ansp);
        ans=0,ansp=0;
        Rep(i,n+1) Rep(j,SI(e[i])) e[i][j]=-e[i][j];
        Rep(i,n+1) reverse(ALL(e[i]));
        Rep(i,n+1) {
            int sz=SI(e[i]);
            if(!sz) continue;
            if(sz>=1) {
                if(e[i][0]>0) ans+=e[i][0];
                if(sz>=2) gmax(ansp,(ll)e[i][1])
            }
        }
        printf("%I64d\n",-ans-ansp);
        Rep(i,n+1) e[i].resize(0);
    }
    return 0;
}

B 序列期望

枚举h

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector 
#define pi pair
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<' ';\
                        cout<m]<#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}

void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (22345)
int T;
ll inj[MAXN],jie[MAXN],inv[MAXN];
void pre(int n) {
    jie[0]=1;For(i,n) jie[i]=mul(jie[i-1],i);
    inj[0]=inj[1]=1;Fork(i,2,n) inj[i]=(F-(F/i))*inj[F%i]%F;
    Rep(i,n+1) inv[i]=inj[i];
    For(i,n) inj[i]=mul(inj[i],inj[i-1]);  
} 
int l[MAXN],r[MAXN];
int main()
{
//  freopen("b.in","r",stdin);
//  freopen(".out","w",stdout);
    int T=read();
    pre(20000);
    while(T--) {
        int n=read();
        For(i,n) l[i]=read(),r[i]=read();
        int minh=*max_element(l+1,l+1+n);
        int maxh=*max_element(r+1,r+1+n);
        ll ind=1;
        For(i,n) ind=ind*inv[r[i]-l[i]+1]%F;
        ll ans=0;
        Fork(h,minh,maxh) {
            ll p1=1,p2=1;
            For(i,n){
                int tl=l[i],tr=min(h,r[i]);
                int pl=h-tl+1,pr=h-tr+1;
                int dis=pl-pr+1;
                ll t=(pl+pr)*(ll)dis/2;
                p1=p1*t%F;

                tl=l[i],tr=min(h-1,r[i]);
                if(tl>tr) {
                    p2=0;//continue;
                }
                pl=h-tl+1,pr=h-tr+1;
                dis=pl-pr+1;
                t=(pl+pr)*(ll)dis/2;
                p2=p2*t%F;
            }
            p1=sub(p1,p2);
            upd(ans,p1);        
        }
        cout<*ind%F<return 0;
}

C 带劲的and和

考虑每个联通块,拆位计算

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector 
#define pi pair
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<' ';\
                        cout<#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}

void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (101010)
int T;
class bingchaji
{
public:
    int father[MAXN],n,cnt;
    void mem(int _n)
    {
        n=_n;
        For(i,n) father[i]=i;
    }
    int getfather(int x) 
    {
        if (father[x]==x) return x;
        return father[x]=getfather(father[x]);
    }
    void unite(int x,int y)
    {
        x=getfather(x);
        y=getfather(y);
        if (x^y) {
            father[x]=y;
        }
    }
    bool same(int x,int y)
    {
        return getfather(x)==getfather(y);
    }
}S;
ll v[MAXN],pow_2[MAXN];
vi G[MAXN];
bool cmp(int x,int y) {
    return v[x]0;
void work(int i) {
    vi vec;
    for(int t:G[i]) vec.pb(t);
    sort(vec.begin(),vec.end(),cmp);
    vector tmp;
    for (ll i=0;i<32;++i) {
        tmp.clear();
        int sz=SI(vec);
        Rep(j,sz)
            if ((v[vec[j]]>>i)&1)
                tmp.push_back(v[vec[j]]);
        int tz=SI(tmp);
        for (int j=1;jint main()
{
//  freopen("cc.in.cpp","r",stdin);
//  freopen(".out","w",stdout);
    int T=read();
    pow_2[0]=1;
    For(i,10000)
        pow_2[i]=pow_2[i-1]*2ll%F;

    while(T--) {
        int n=read(),m=read();
        S.mem(n+1);
        For(i,n) v[i]=read();
        For(i,m) {
            int x=read(),y=read();
            S.unite(x,y);
        }
        For(i,n) S.father[i]=S.getfather(i);
        For(i,n) {
            G[S.father[i]].pb(i);   
        }
        res=0;
        For(i,n) if(SI(G[i])) {
            work(i);
        }
        printf("%I64d\n",res);
        For(i,n) G[i].clear();
    }
    return 0;
}

D 公共子序列

显然1个5元对(a[i]=b[j]=c[k]=d[l]=e[m])出现的期望对数是O(n),因此可以暴力解决
注意虽然是期望O(n)但是实际可能大于n对

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector 
#define pi pair
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<' ';\
                        cout<#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (1010)
#define MAXM (666666)
int T;
int a[10][MAXN];
vi v[10][MAXN];
int st[10];
int tot=0,n,k,f[MAXM][10];
int id[MAXM];
bool cmp(int i,int j) {
    return f[i][1]1];
}
void dfs(int i,int l) {
    if(l>k) {
        ++tot;
        For(t,k) f[tot][t]=st[t];
        return ;    
    }
    for(int j:v[l][i]) {
        st[l]=j;
        dfs(i,l+1);
    }
}
bool les(int i,int j) {//i
    For(l,k) {
        if(f[i][l]>=f[j][l]) return 0;
    }return 1;
}
ll g[MAXM];
int main()
{
//  freopen("d.in","r",stdin);
//  freopen(".out","w",stdout);
    int T=read();
    while(T--) {
        k=read(),n=read();
        For(i,k) For(j,n) a[i][j]=read();
        For(i,k) {
            For(j,n) v[i][a[i][j]].pb(j);
        }
        tot=0;
        For(i,n) {
            dfs(i,1);
        }
        For(i,tot) id[i]=i;
        sort(id+1,id+1+tot,cmp);
        ll res=0;
        For(i,tot) {
            g[i]=1;
            For(j,i-1) if (les(id[j],id[i])) {
                    upd(g[i],g[j]);
                }
            upd(res,g[i]);
        }
        cout<0);
    }
    return 0;
}

E 棋盘上的旅行

随机对图重染色若干次,然后bfs。
注意随机次数必须足够多。

F

你可能感兴趣的:(比赛题解)