https://acm.bnu.edu.cn/v3/statments/***2016.pdf


题意:给定a数组和b数组。求c数组要求c[k]=max(a[i]+b[j])其中i+j==k||i+j==k+n

做法:一直在想如何降低时间复杂度未果,看了Ac代码觉得似曾相识??

由于要凑数嘛,而且尽量a[i]+b[j]的值比较大,比赛的时候推导出我可以设a'[i] b'[j]是之前那两个数组下标和值调换过来,那么就是求两个和等于给定值k时,下标和的最大值i。枚举下标和,ans[k]=i表示欲求的数组,用不着跑很多数字就可以求出来啦

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
    int id,value;
}a[200009],b[200009];
bool cmp(node x,node y)
{
    return x.value<y.value;
}
int n;
int ans[200009];

int main()
{
   //freopen("cin.txt","r",stdin);
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i].value);
            a[i].id=i;
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&b[i].value);
            b[i].id=i;
        }
        sort(a,a+n,cmp);
        sort(b,b+n,cmp);
        memset(ans,-1,sizeof(ans));
        int tot=0;
        for(int i=2*n-2;i>=0;i--)
        {
            for(int j=n-1;j>=0&&i-j<=n-1&&i-j>=0;j--)
            {
                int k=(a[j].id+b[i-j].id)%n;
                if(ans[k]==-1)
                {
                    ans[k]=i;
                  //  printf("k=%d,i=%d\n",k,ans[k]);
                    tot++;
                    if(tot==n)break;
                }
            }
            if(tot==n)break;//must!!!这个错误很脑残啊,
//这句话怎么能不写呢==取模可以不优化,也可以不用函数
        }
        for(int i=0;i<n-1;i++)printf("%d ",ans[i]);
        printf("%d\n",ans[n-1]);
    }
    return 0;
}