码迷,mamicode.com
首页 > 其他好文 > 详细

BestCoder Round #65 hdu5592 5593 5594

时间:2018-01-07 00:38:30      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:pos   +=   ret   排列   tar   个数   tin   har   etc   

hdu5592 - ZYB‘s Premutation 

http://acm.hdu.edu.cn/showproblem.php?pid=5592

对于一个X=a[i]-a[i-1],它可以表示为原排列第i个位置的数,在它前面有X个比它大的数,也就是说在1到i的区间内第i个数为该区间内第X+1大的数

那么可以考虑倒着求出原排列:对于最后一个数,令k=a[n]-a[n-1],最后一个数就是k+1;而对于倒数第二个数,令k‘=a[n-1]-a[n-2],则该位置的答案为从1到n中除去k,第k‘+1大的数。。。以此类推

所以可以用线段树维护以上操作

 

#include<bits/stdc++.h>
#define MAXN 50005
using namespace std;
int sum[MAXN*4],n;
inline void build(int l,int r,int pos)
{
    if(l==r)
    {
        sum[pos]=1;
        return;
    }
    int mid=l+r>>1;
    build(l,mid,pos<<1);
    build(mid+1,r,pos<<1|1);
    sum[pos]=sum[pos<<1]+sum[pos<<1|1];
}
inline int query(int l,int r,int k,int pos)
{
    sum[pos]--;
    if(l==r)
    {
        sum[pos]=0;
        return l;
    }
    int mid=l+r>>1;
    if(k<=sum[pos<<1]) return query(l,mid,k,pos<<1);
    else return query(mid+1,r,k-sum[pos<<1],pos<<1|1);
}
int a[MAXN],ans[MAXN];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        memset(sum,0,sizeof(sum));
        build(1,n,1);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=n;i>=1;i--)
        {
            int x=a[i]-a[i-1]+1;
            ans[i]=query(1,n,i-x+1,1);
        }
        for(int i=1;i<=n;i++)
            printf("%d%c",ans[i],(i==n)?‘\n‘:‘ ‘);
    }
}

 

  

 

 

hdu5593 - ZYB‘s Tree  

http://acm.hdu.edu.cn/showproblem.php?pid=5593 

树形dp

设ans[i][j]为第i个点距离为j的点的个数

ans[i][j]有两部分构成:一部分来源它的子树,一部分来源它的父亲

设它的子树的答案为f[i][j],它的父亲的答案为g[i][j]

所以 ans[i][j]=f[i][j]+g[i][j];

   f[i][j]=Σf[son][j-1]

   g[i][j]=ans[fa][j-1]-f[i][j-2]

 

#include<bits/stdc++.h>
#define MAXN 500050
using namespace std;
struct Edge
{
    int v,next;
}e[MAXN*2];
int head[MAXN],cnt=0;
inline void add(int u,int v){cnt++;e[cnt].v=v;e[cnt].next=head[u];head[u]=cnt;}
int ans[MAXN][12],f[MAXN][12],g[MAXN][12],n,k,a,b;
void dfs(int x,int fa)
{
    f[x][0]=1;
    for(int i=head[x];i;i=e[i].next)
    {
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,x);
        for(int j=1;j<=k;j++)
            f[x][j]+=f[v][j-1];
    }
}
void dfs1(int x,int fa)
{
    if(fa==0)
    {
        for(int i=0;i<=k;i++)
            ans[x][i]=f[x][i];    
    }
    else
    {
        g[x][0]=0;ans[x][0]=1;
        g[x][1]=1;ans[x][1]=f[x][1]+g[x][1];
        for(int i=2;i<=k;i++)
        {
            g[x][i]=ans[fa][i-1]-f[x][i-2];
            ans[x][i]=f[x][i]+g[x][i];
        }
    }
    for(int i=head[x];i;i=e[i].next)
    {
        int v=e[i].v;
        if(v==fa) continue;
        dfs1(v,x);
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        cnt=0;
        memset(head,0,sizeof(head));
        memset(f,0,sizeof(f));
        memset(g,0,sizeof(g));
        memset(ans,0,sizeof(ans));
        scanf("%d%d%d%d",&n,&k,&a,&b);
        for(int i=2;i<=n;i++)
        {
            int fa=((long long)a*i+b)%(i-1)+1;
            add(fa,i);add(i,fa);
        }
        dfs(1,0);dfs1(1,0);
        int Ans=0;
        for(int i=1;i<=n;i++)
        {
            int res=0;
            for(int j=0;j<=k;j++)
                res+=ans[i][j];
            Ans^=res;
        }
        printf("%d\n",Ans);
    }
}

  

hdu5594 - ZYB‘s Prime  

http://acm.hdu.edu.cn/showproblem.php?pid=5594

官方题解:

技术分享图片

 

#include<bits/stdc++.h>
#define MAXN 100050
#define inf 0x3f3f3f3f
using namespace std;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
struct Edge
{
    int v,cap,next;
}e[MAXN];
int head[MAXN],cnt=1;
inline void addedge(int u,int v,int cap)
{
    e[++cnt]=(Edge){v,cap,head[u]};head[u]=cnt;
    e[++cnt]=(Edge){u,0,head[v]};head[v]=cnt;
}
bool vis[MAXN];
int dis[MAXN],cur[MAXN],S,T,n;
bool bfs()
{
    queue<int>q;
    memset(vis,0,sizeof(vis));
    q.push(S);dis[S]=0;vis[S]=1;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].v;
            if(vis[v]||e[i].cap==0) continue;
            dis[v]=dis[u]+1;
            vis[v]=1;
            q.push(v);
        }
    }
    return vis[T];
}
int dfs(int x,int a)
{
    if(x==T||a==0) return a;
    int flow=0;
    for(int &i=cur[x];i;i=e[i].next)
    {
        int v=e[i].v;
        if(dis[v]==dis[x]+1&&e[i].cap)
        {
            int f=dfs(v,min(e[i].cap,a-flow));
            if(f)
            {
                e[i].cap-=f;
                e[i^1].cap+=f;
                flow+=f;
            }
            if(flow==a) break;
        }
    }
    return flow;
}
inline int maxflow()
{
    int ans=0,flow;
    while(bfs())
    {
        for(int i=S;i<=T+5;i++) cur[i]=head[i];
        while(flow=dfs(S,inf)) ans+=flow;
    }
    return ans;
}
inline bool isprime(int x)
{
    for(int i=2;i<=sqrt(x);i++)
        if(x%i==0) return 0;
    return 1;
}
int a1[205],a2[205],s1,s2,s3;
int main()
{
    int TT=read();
    while(TT--)
    {
        memset(head,0,sizeof(head));
        cnt=1;s1=s2=s3=0;
        n=read();
        for(int i=1;i<=n;i++)
        {
            int x=read();
            if(x&1)
            {
                if(x==1) s3++;
                else a1[++s1]=x;
            }
            else a2[++s2]=x;
        }
        if(s1>s2||s1+s3<s2)
        {
            puts("NO");
            continue;
        }
        if(s1==s2&&s3==2)
        {
            puts("NO");
            continue;
        }
        S=0,T=2*s2+1;
        for(int i=1;i<=s2;i++) addedge(S,i,2),addedge(i+s2,T,2);
        for(int i=1;i<=s1;i++)
            for(int j=1;j<=s2;j++)
                if(isprime(a1[i]+a2[j])) addedge(i,j+s2,1);
        int x;
        if(s3>s2-s1) x=2;
        else x=1;
        for(int i=1;i<=s2-s1;i++)
            for(int j=1;j<=s2;j++)
                if(isprime(1+a2[j])) addedge(i+s1,j+s2,x);
        if(maxflow()==2*s2) puts("YES");
        else puts("NO");
    }
}

  

 

BestCoder Round #65 hdu5592 5593 5594

标签:pos   +=   ret   排列   tar   个数   tin   har   etc   

原文地址:https://www.cnblogs.com/Position/p/8215558.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!