CF1214E Petya and Construction Set题解

原来这就叫构造题,❤了


这道题的做法,我自己诌了一个形象的名字——“挂葡萄”法(
首先,“搭葡萄架”:考虑到每个距离 \(d_i\) 只与 \(2i-1,2i\) 有关,\(2i-1\)\(2(i+1)-1\) 之间的距离是可以随意设置的,那不妨把所有的奇数编号串成一条链(不过注意,链上的编号不一定是按顺序的,因为要顺应题目要求的距离)。
然后,“挂葡萄”:将 \(d\) 数组降序排序,对于每个 \(d_i\),将其按照距离挂在 \(i+d_i-1\) 下面,如果 \(i+d_i-1\) 是链上最后一个或超过了最后一个,则需要把链长度 \(+1\)
正确性?不显然吗(真的挺显然的⑧……
具体看代码:

#include 
#include 
#include 
using namespace std;

const int N=1e6+3;
struct Node{int val,id;}d[N];
vector G[N];
int t[N],n,tot;

bool cmp(Node a,Node b) {return a.val>b.val;}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&d[i].val),d[i].id=i;
    sort(d+1,d+n+1,cmp);
    for(int i=1;i<=n;++i) t[i]=d[i].id*2-1; //搭架子
    int tot=n;
    for(int i=1;i<=n;++i)
    {
        if(i+d[i].val-1>=tot) t[++tot]=t[i]+1; //如果不行就要往后延
        else G[t[i+d[i].val-1]].push_back(t[i]+1);    //挂葡萄
    }
    for(int i=1;i<=tot;++i)
    {
        if(i

你可能感兴趣的:(CF1214E Petya and Construction Set题解)