2019 Multi-University Training Contest 6

25 篇文章 0 订阅
18 篇文章 0 订阅

hdu6639:Faraway

theme:给定n与m,n代表方程个数,给定n个方程的xi,yi,ki,ti,求满足一下式子的xe,ye数目。1<=n<=10,1<=m<=1e9,0≤xi,yi≤m,2≤ki≤5,0≤ti<ki

solution:首先取绝对值,对xi,yi分别排序后有10*10个区域,每个确定的区域可以去掉绝对值(xi-xe+yi-ye)。

#include<bits/stdc++.h>
typedef long long ll;
#define inf 0x3f3f3f3f
using namespace std;
#define far(i,s,n) for(int i=s;i<n;++i)
int K=60;
int n;

struct _a
{
    int k,t;
    ll x,y;
}a[20];
ll X[20],Y[20];

bool check(ll x,ll y)
{
    far(i,0,n)
    {
        if((abs(a[i].x-x)+abs(a[i].y-y))%a[i].k!=a[i].t)
            return 0;
    }
    return 1;
}

ll cul(ll l,ll r)
{
    r-=l+1;
    if(r<0)
        return 0;
    return r/K+1;
}

int main()
{
    int Case;
    cin>>Case;
    while(Case--)
    {
        ll m;
        scanf("%d%lld",&n,&m);
        far(i,0,n)
        {
            scanf("%lld%lld%d%d",&a[i].x,&a[i].y,&a[i].k,&a[i].t);
            X[i+1]=a[i].x;
            Y[i+1]=a[i].y;
        }
        ll ans=0;
        X[n+1]=m+1;
        Y[n+1]=m+1;
        sort(X+1,X+n+2);
        sort(Y+1,Y+n+2);
       // int flag=0;
        far(i,0,n+1)
            if(X[i]<X[i+1])
                far(j,0,n+1)
                    if(Y[j]<Y[j+1])
                        far(x,0,K)
                            far(y,0,K)
                                if(check(X[i]+x,Y[j]+y))
                                {
                                    //++flag;
                                    ans+=cul(X[i]+x,X[i+1])*cul(Y[j]+y,Y[j+1]);
                                    //cout<<i<<" "<<j<<" "<<x<<" "<<y<<" "<<ans<<endl;

                                }
        printf("%lld\n",ans);
    }
}

hdu6635:Nonsense Time

theme:给定长度为n的序列,开始时所有元素都被冻住,即不可用,然后没次解冻某个元素Api,问当前可用元素的最长非降子序列长度为多少 ?1<=n<=50000,1<=Ai<=n,1<=pi<=n

solution:逆向考虑。先求出所有元素的最长非降子序列,然后倒序删除元素,若被删除的元素不是上一个最长非降子序列的关键元素,则长度不变,冻结它就行,否则冻住它,再算一遍最长非降子序列。用贪心+二分算最长非降子序列复杂度为o(nlogn),由于数据随机,所以LIS期望长度为sqrt(n),所以总时间复杂度为o(sqrt(n)*n*logn).

#include<bits/stdc++.h>
typedef long long LL;
#define inf 0x3f3f3f3f
using namespace std;
#define far(i,s,n) for(int i=s;i<n;++i)

int a[50050],fidx[50050];
int dp[50050],idx[50050],belong[50050];//dp存LIS元素,idx[i]表示a[i]能在dp中的位置下标,belong[i]标识a[i]是否为LIS关键元素
int ans[50050];
int n;
void Find()//找LIS
{
    fill(dp,dp+n,inf);
    fill(idx,idx+n,-1);
    fill(belong,belong+n,0);
    int maxl=0;
    far(i,0,n)
    {
        if(a[i]!=inf)//表示a[i]没被冻住
        {
            int pos=lower_bound(dp,dp+n,a[i])-dp;
            if(dp[pos]==inf)//a[i]比dp里所有元素都大,则把它加在后面
            {
                dp[pos]=a[i];
                idx[i]=pos;
                maxl = pos;
            }
            else
            {
                dp[pos]=a[i];//用较小的值替换
                idx[i]=pos;
            }
        }
    }
    for(int i=n-1;i>=0;--i)//判断每个元素是否为关键元素,即每个该长度的LIS都有它
    {
        if(maxl<0)
            break;
        if(idx[i]==maxl)
        {
            belong[i]=1;
            --maxl;
        }
    }
}

int main()
{
    int Case;
    cin>>Case;
    while(Case--)
    {
        scanf("%d",&n);
        far(i,0,n)
            scanf("%d",&a[i]);
        Find();
        far(i,0,n)
        {
            scanf("%d",&fidx[i]);
            --fidx[i];
        }
        for(int i=n-1;i>=0;--i)
        {
            ans[i]=lower_bound(dp,dp+n,inf)-dp;
            if(belong[fidx[i]]==1)
            {
                a[fidx[i]]=inf;
                Find();
            }
            else
                a[fidx[i]]=inf;
        }
        far(i,0,n)
        {
            if(i==n-1)
                printf("%d\n",ans[i]);
            else
                printf("%d ",ans[i]);
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值