zoukankan      html  css  js  c++  java
  • 【uoj#143】[UER #5]万圣节的数列 构造

    题目描述

    给出一个的数列,将其重新排列,使得其等差子序列的数目最小。输出一种可能的排列后的数列。


    题解

    构造

    那天和 EdwardFrog 讨论 bzoj2124 的构造时突然有的灵感,最后发现就是这道题...

    通过构造可以使得不存在长度为3的等差子序列。

    考虑:如果把所有奇数放到所有偶数的左面,那么就不会出现 “奇-偶-奇” 或 “偶-奇-偶” 的情况。

    对于 “奇-奇-奇” 或 “偶-偶-偶” 的情况,将所有 $a_i$ 变为 $lfloorfrac{a_i}2 floor$ 不影响判断,因此将所有数除以2后重复这个过程即可。

    由于一个数除以 $log n$ 次就会变成1,因此这个过程只需要进行 $log$ 次。

    每一层都只会处理 $n$ 个数,时间复杂度 $O(nlog n)$ 。

    #include <cstdio>
    int a[510] , p[510] , t[510];
    void solve(int l , int r , int x)
    {
    	if(!x || l >= r) return;
    	int i , b = l , e = r;
    	for(i = l ; i <= r ; i ++ )
    	{
    		if(a[p[i]] & 1) t[b ++ ] = p[i];
    		else t[e -- ] = p[i];
    	}
    	for(i = l ; i <= r ; i ++ ) a[p[i]] >>= 1 , p[i] = t[i];
    	solve(l , e , x - 1) , solve(b , r , x - 1);
    }
    int main()
    {
    	int n , i;
    	scanf("%d" , &n);
    	for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , p[i] = i;
    	solve(1 , n , 30);
    	for(i = 1 ; i <= n ; i ++ ) printf("%d " , p[i]);
    	return 0;
    }
    
  • 相关阅读:
    more命令
    mktemp命令
    有效的括号字符串
    mc命令
    字符串相加
    Vue中虚拟DOM的理解
    chattr命令
    记近一年线上项目经验及架构变更记录
    微博AnalysisQl动态数据视图元数据设计
    搭建prometheus+grafana监控SpringBoot应用入门
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8677219.html
Copyright © 2011-2022 走看看