codeforces:C. Almost All Multiples【构造 + 贪心】

news/2024/11/29 21:42:09/

目录

  • 题目截图
  • 题目分析
  • ac code
  • 总结

题目截图

在这里插入图片描述

题目分析

  • 现在p1 = x, pn = 1
  • 如果我们一开始按1234…这样放字典序是最小的
  • 所以根据这个思路,我们还是按这个构造:那么我们的n被挤出来了,只能放到px上
  • 所以如果一开始x不能整除n的话,就直接-1了
  • 如果能的话,我们希望得到最小的字典序
  • 思路也就是贪心,从左到右遍历i,一碰到i和x能交换的就交换
  • 因为这样交换替换的px一定是最小的
  • 能交换的条件是:a[x] % (i + 1) = 0 and a[i] % (x + 1) = 0
  • 交换后更新一下x = i即可,继续向后遍历i
  • 注意到i >= x + 1,所以x是单调递增的
  • 就是说,我们把n最放最靠后了,也是符合目标的
  • 同时我们交换n的时候,那个交换到x位置的是一定也是最小的

ac code

# -*- coding: utf-8 -*-
# @Time    : 2022/12/2 15:51
# @Author  : bridgekiller
# @FileName: 1758C.py
# @Software: PyCharm
# @Blog    :bridge-killer.blog.csdn.netimport os
import sys
import math
import random
import threading
from copy import deepcopy
from io import BytesIO, IOBase
from types import GeneratorType
from functools import lru_cache, reduce
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque
from itertools import accumulate, combinations, permutations
from heapq import nsmallest, nlargest, heapify, heappop, heappush
from typing import Generic, Iterable, Iterator, TypeVar, Union, Listdef debug(func):def wrapper(*args, **kwargs):print('----------------')res = func(*args, **kwargs)print('----------------')return resreturn wrapperdef bootstrap(f, stack=[]):def wrappedfunc(*args, **kwargs):if stack:return f(*args, **kwargs)else:to = f(*args, **kwargs)while True:if type(to) is GeneratorType:stack.append(to)to = next(to)else:stack.pop()if not stack:breakto = stack[-1].send(to)return toreturn wrappedfuncclass SegTree:'''支持增量更新,覆盖更新,序列更新,任意RMQ操作基于二叉树实现初始化:O(1)增量更新或覆盖更新的单次操作复杂度:O(log k)序列更新的单次复杂度:O(n)'''def __init__(self, f1, f2, l, r, v=0):'''初始化线段树[left,right)f1,f2示例:线段和:f1=lambda a,b:a+bf2=lambda a,n:a*n线段最大值:f1=lambda a,b:max(a,b)f2=lambda a,n:a线段最小值:f1=lambda a,b:min(a,b)f2=lambda a,n:a'''self.ans = f2(v, r - l)self.f1 = f1self.f2 = f2self.l = l  # leftself.r = r  # rightself.v = v  # init valueself.lazy_tag = 0  # Lazy tagself.left = None  # SubTree(left,bottom)self.right = None  # SubTree(right,bottom)@propertydef mid_h(self):return (self.l + self.r) // 2def create_subtrees(self):midh = self.mid_hif not self.left and midh > self.l:self.left = SegTree(self.f1, self.f2, self.l, midh)if not self.right:self.right = SegTree(self.f1, self.f2, midh, self.r)def init_seg(self, M):'''将线段树的值初始化为矩阵Matrx输入保证Matrx与线段大小一致'''m0 = M[0]self.lazy_tag = 0for a in M:if a != m0:breakelse:self.v = m0self.ans = self.f2(m0, len(M))return self.ansself.v = '#'midh = self.mid_hself.create_subtrees()self.ans = self.f1(self.left.init_seg(M[:midh - self.l]), self.right.init_seg(M[midh - self.l:]))return self.ansdef cover_seg(self, l, r, v):'''将线段[left,right)覆盖为val'''if self.v == v or l >= self.r or r <= self.l:return self.ansif l <= self.l and r >= self.r:self.v = vself.lazy_tag = 0self.ans = self.f2(v, self.r - self.l)return self.ansself.create_subtrees()if self.v != '#':if self.left:self.left.v = self.vself.left.ans = self.f2(self.v, self.left.r - self.left.l)if self.right:self.right.v = self.vself.right.ans = self.f2(self.v, self.right.r - self.right.l)self.v = '#'# push upself.ans = self.f1(self.left.cover_seg(l, r, v), self.right.cover_seg(l, r, v))return self.ansdef inc_seg(self, l, r, v):'''将线段[left,right)增加val'''if v == 0 or l >= self.r or r <= self.l:return self.ans# self.ans = '?'if l <= self.l and r >= self.r:if self.v == '#':self.lazy_tag += velse:self.v += vself.ans += self.f2(v, self.r - self.l)return self.ansself.create_subtrees()if self.v != '#':self.left.v = self.vself.left.ans = self.f2(self.v, self.left.r - self.left.l)self.right.v = self.vself.right.ans = self.f2(self.v, self.right.r - self.right.l)self.v = '#'self.pushdown()self.ans = self.f1(self.left.inc_seg(l, r, v), self.right.inc_seg(l, r, v))return self.ansdef inc_idx(self, idx, v):'''increase idx by val'''if v == 0 or idx >= self.r or idx < self.l:return self.ansif idx == self.l == self.r - 1:self.v += vself.ans += self.f2(v, 1)return self.ansself.create_subtrees()if self.v != '#':self.left.v = self.vself.left.ans = self.f2(self.v, self.left.r - self.left.l)self.right.v = self.vself.right.ans = self.f2(self.v, self.right.r - self.right.l)self.v = '#'self.pushdown()self.ans = self.f1(self.left.inc_idx(idx, v), self.right.inc_idx(idx, v))return self.ansdef pushdown(self):if self.lazy_tag != 0:if self.left:if self.left.v != '#':self.left.v += self.lazy_tagself.left.lazy_tag = 0else:self.left.lazy_tag += self.lazy_tagself.left.ans += self.f2(self.lazy_tag, self.left.r - self.left.l)if self.right:if self.right.v != '#':self.right.v += self.lazy_tagself.right.lazy_tag = 0else:self.right.lazy_tag += self.lazy_tagself.right.ans += self.f2(self.lazy_tag, self.right.r - self.right.l)self.lazy_tag = 0def query(self, l, r):'''查询线段[right,bottom)的RMQ'''if l >= r: return 0if l <= self.l and r >= self.r:return self.ansif self.v != '#':return self.f2(self.v, min(self.r, r) - max(self.l, l))midh = self.mid_hanss = []if l < midh:anss.append(self.left.query(l, r))if r > midh:anss.append(self.right.query(l, r))return reduce(self.f1, anss)class SortedList:def __init__(self, iterable=[], _load=200):"""Initialize sorted list instance."""values = sorted(iterable)self._len = _len = len(values)self._load = _loadself._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]self._list_lens = [len(_list) for _list in _lists]self._mins = [_list[0] for _list in _lists]self._fen_tree = []self._rebuild = Truedef _fen_build(self):"""Build a fenwick tree instance."""self._fen_tree[:] = self._list_lens_fen_tree = self._fen_treefor i in range(len(_fen_tree)):if i | i + 1 < len(_fen_tree):_fen_tree[i | i + 1] += _fen_tree[i]self._rebuild = Falsedef _fen_update(self, index, value):"""Update `fen_tree[index] += value`."""if not self._rebuild:_fen_tree = self._fen_treewhile index < len(_fen_tree):_fen_tree[index] += valueindex |= index + 1def _fen_query(self, end):"""Return `sum(_fen_tree[:end])`."""if self._rebuild:self._fen_build()_fen_tree = self._fen_treex = 0while end:x += _fen_tree[end - 1]end &= end - 1return xdef _fen_findkth(self, k):"""Return a pair of (the largest `idx` such that `sum(_fen_tree[:idx]) <= k`, `k - sum(_fen_tree[:idx])`)."""_list_lens = self._list_lensif k < _list_lens[0]:return 0, kif k >= self._len - _list_lens[-1]:return len(_list_lens) - 1, k + _list_lens[-1] - self._lenif self._rebuild:self._fen_build()_fen_tree = self._fen_treeidx = -1for d in reversed(range(len(_fen_tree).bit_length())):right_idx = idx + (1 << d)if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:idx = right_idxk -= _fen_tree[idx]return idx + 1, kdef _delete(self, pos, idx):"""Delete value at the given `(pos, idx)`."""_lists = self._lists_mins = self._mins_list_lens = self._list_lensself._len -= 1self._fen_update(pos, -1)del _lists[pos][idx]_list_lens[pos] -= 1if _list_lens[pos]:_mins[pos] = _lists[pos][0]else:del _lists[pos]del _list_lens[pos]del _mins[pos]self._rebuild = Truedef _loc_left(self, value):"""Return an index pair that corresponds to the first position of `value` in the sorted list."""if not self._len:return 0, 0_lists = self._lists_mins = self._minslo, pos = -1, len(_lists) - 1while lo + 1 < pos:mi = (lo + pos) >> 1if value <= _mins[mi]:pos = mielse:lo = miif pos and value <= _lists[pos - 1][-1]:pos -= 1_list = _lists[pos]lo, idx = -1, len(_list)while lo + 1 < idx:mi = (lo + idx) >> 1if value <= _list[mi]:idx = mielse:lo = mireturn pos, idxdef _loc_right(self, value):"""Return an index pair that corresponds to the last position of `value` in the sorted list."""if not self._len:return 0, 0_lists = self._lists_mins = self._minspos, hi = 0, len(_lists)while pos + 1 < hi:mi = (pos + hi) >> 1if value < _mins[mi]:hi = mielse:pos = mi_list = _lists[pos]lo, idx = -1, len(_list)while lo + 1 < idx:mi = (lo + idx) >> 1if value < _list[mi]:idx = mielse:lo = mireturn pos, idxdef add(self, value):"""Add `value` to sorted list."""_load = self._load_lists = self._lists_mins = self._mins_list_lens = self._list_lensself._len += 1if _lists:pos, idx = self._loc_right(value)self._fen_update(pos, 1)_list = _lists[pos]_list.insert(idx, value)_list_lens[pos] += 1_mins[pos] = _list[0]if _load + _load < len(_list):_lists.insert(pos + 1, _list[_load:])_list_lens.insert(pos + 1, len(_list) - _load)_mins.insert(pos + 1, _list[_load])_list_lens[pos] = _loaddel _list[_load:]self._rebuild = Trueelse:_lists.append([value])_mins.append(value)_list_lens.append(1)self._rebuild = Truedef discard(self, value):"""Remove `value` from sorted list if it is a member."""_lists = self._listsif _lists:pos, idx = self._loc_right(value)if idx and _lists[pos][idx - 1] == value:self._delete(pos, idx - 1)def remove(self, value):"""Remove `value` from sorted list; `value` must be a member."""_len = self._lenself.discard(value)if _len == self._len:raise ValueError('{0!r} not in list'.format(value))def pop(self, index=-1):"""Remove and return value at `index` in sorted list."""pos, idx = self._fen_findkth(self._len + index if index < 0 else index)value = self._lists[pos][idx]self._delete(pos, idx)return valuedef bisect_left(self, value):"""Return the first index to insert `value` in the sorted list."""pos, idx = self._loc_left(value)return self._fen_query(pos) + idxdef bisect_right(self, value):"""Return the last index to insert `value` in the sorted list."""pos, idx = self._loc_right(value)return self._fen_query(pos) + idxdef count(self, value):"""Return number of occurrences of `value` in the sorted list."""return self.bisect_right(value) - self.bisect_left(value)def __len__(self):"""Return the size of the sorted list."""return self._lendef __getitem__(self, index):"""Lookup value at `index` in sorted list."""pos, idx = self._fen_findkth(self._len + index if index < 0 else index)return self._lists[pos][idx]def __delitem__(self, index):"""Remove value at `index` from sorted list."""pos, idx = self._fen_findkth(self._len + index if index < 0 else index)self._delete(pos, idx)def __contains__(self, value):"""Return true if `value` is an element of the sorted list."""_lists = self._listsif _lists:pos, idx = self._loc_left(value)return idx < len(_lists[pos]) and _lists[pos][idx] == valuereturn Falsedef __iter__(self):"""Return an iterator over the sorted list."""return (value for _list in self._lists for value in _list)def __reversed__(self):"""Return a reverse iterator over the sorted list."""return (value for _list in reversed(self._lists) for value in reversed(_list))def __repr__(self):"""Return string representation of sorted list."""return 'SortedList({0})'.format(list(self))T = TypeVar('T')class SortedSet(Generic[T]):BUCKET_RATIO = 50REBUILD_RATIO = 170def _build(self, a=None) -> None:"Evenly divide `a` into buckets."if a is None: a = list(self)size = self.size = len(a)bucket_size = int(math.ceil(math.sqrt(size / self.BUCKET_RATIO)))self.a = [a[size * i // bucket_size: size * (i + 1) // bucket_size] for i in range(bucket_size)]def __init__(self, a: Iterable[T] = []) -> None:"Make a new SortedSet from iterable. / O(N) if sorted and unique / O(N log N)"a = list(a)if not all(a[i] < a[i + 1] for i in range(len(a) - 1)):a = sorted(set(a))self._build(a)def __iter__(self) -> Iterator[T]:for i in self.a:for j in i: yield jdef __reversed__(self) -> Iterator[T]:for i in reversed(self.a):for j in reversed(i): yield jdef __len__(self) -> int:return self.sizedef __repr__(self) -> str:return "SortedSet" + str(self.a)def __str__(self) -> str:s = str(list(self))return "{" + s[1: len(s) - 1] + "}"def _find_bucket(self, x: T) -> List[T]:"Find the bucket which should contain x. self must not be empty."for a in self.a:if x <= a[-1]: return areturn adef __contains__(self, x: T) -> bool:if self.size == 0: return Falsea = self._find_bucket(x)i = bisect_left(a, x)return i != len(a) and a[i] == xdef add(self, x: T) -> bool:"Add an element and return True if added. / O(√N)"if self.size == 0:self.a = [[x]]self.size = 1return Truea = self._find_bucket(x)i = bisect_left(a, x)if i != len(a) and a[i] == x: return Falsea.insert(i, x)self.size += 1if len(a) > len(self.a) * self.REBUILD_RATIO:self._build()return Truedef discard(self, x: T) -> bool:"Remove an element and return True if removed. / O(√N)"if self.size == 0: return Falsea = self._find_bucket(x)i = bisect_left(a, x)if i == len(a) or a[i] != x: return Falsea.pop(i)self.size -= 1if len(a) == 0: self._build()return Truedef lt(self, x: T) -> Union[T, None]:"Find the largest element < x, or None if it doesn't exist."for a in reversed(self.a):if a[0] < x:return a[bisect_left(a, x) - 1]def le(self, x: T) -> Union[T, None]:"Find the largest element <= x, or None if it doesn't exist."for a in reversed(self.a):if a[0] <= x:return a[bisect_right(a, x) - 1]def gt(self, x: T) -> Union[T, None]:"Find the smallest element > x, or None if it doesn't exist."for a in self.a:if a[-1] > x:return a[bisect_right(a, x)]def ge(self, x: T) -> Union[T, None]:"Find the smallest element >= x, or None if it doesn't exist."for a in self.a:if a[-1] >= x:return a[bisect_left(a, x)]def __getitem__(self, x: int) -> T:"Return the x-th element, or IndexError if it doesn't exist."if x < 0: x += self.sizeif x < 0: raise IndexErrorfor a in self.a:if x < len(a): return a[x]x -= len(a)raise IndexErrordef index(self, x: T) -> int:"Count the number of elements < x."ans = 0for a in self.a:if a[-1] >= x:return ans + bisect_left(a, x)ans += len(a)return ansdef index_right(self, x: T) -> int:"Count the number of elements <= x."ans = 0for a in self.a:if a[-1] > x:return ans + bisect_right(a, x)ans += len(a)return ansBUFSIZE = 4096class FastIO(IOBase):newlines = 0def __init__(self, file):self._fd = file.fileno()self.buffer = BytesIO()self.writable = "x" in file.mode or "r" not in file.modeself.write = self.buffer.write if self.writable else Nonedef read(self):while True:b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))if not b:breakptr = self.buffer.tell()self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)self.newlines = 0return self.buffer.read()def readline(self):while self.newlines == 0:b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))self.newlines = b.count(b"\n") + (not b)ptr = self.buffer.tell()self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)self.newlines -= 1return self.buffer.readline()def flush(self):if self.writable:os.write(self._fd, self.buffer.getvalue())self.buffer.truncate(0), self.buffer.seek(0)class IOWrapper(IOBase):def __init__(self, file):self.buffer = FastIO(file)self.flush = self.buffer.flushself.writable = self.buffer.writableself.write = lambda s: self.buffer.write(s.encode("ascii"))self.read = lambda: self.buffer.read().decode("ascii")self.readline = lambda: self.buffer.readline().decode("ascii")sys.stdin = IOWrapper(sys.stdin)
sys.stdout = IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")def I():return input()def II():return int(input())def MI():return map(int, input().split())def LI():return list(input().split())def LII():return list(map(int, input().split()))def GMI():return map(lambda x: int(x) - 1, input().split())def LGMI():return list(map(lambda x: int(x) - 1, input().split()))def solve():n, x = LII()if n % x: # n想放到x上return print(-1)a = list(range(1, n + 1))if n == x:a[0], a[-1] = a[-1], a[0]return print(*a)# 1和x放了,n就放到x那里a[0], a[-1], a[x - 1] = x, 1, nx -= 1# 获得最小字典序for i in range(1, n-1):# i >= x# a[i] and a[x]是可以交换的# n能往后挪就往后挪if a[x] % (i + 1) == 0 and a[i] % (x + 1) == 0:a[i], a[x] = a[x], a[i]x = iprint(*a)if __name__ == '__main__':for _ in range(II()):solve()

总结

  • 最小字典序联想到12345…
  • 固定了p1和pn的值,联想到px = n
  • 为了获得最小字典序,需要让n尽可能往后,需要与后面元素交换
  • 同一个位置或许有多个能和x交换的i(i > x)
  • 我们选最近的,因为这样第x个位置上的数就会最小
  • 一方面使得n放的相对后,另一方面使得n之前的位置放的数是最小的

http://www.ppmy.cn/news/890.html

相关文章

【Python游戏】用Python实现一个测试你智商的小游戏——24点,过不了三关的都是细狗 | 附带源码

前言 好咯&#xff0c;包子们下午好 今天小编主要是过来测试一下大家的智商&#xff0c;没别的意思&#xff0c;不是看不起大家&#xff0c;我感觉今天实现的小游戏&#xff0c;可能大家真的过不了三关&#xff01; 哈哈哈&#xff0c;废话不多说吧 直接开始我们的游戏实现功能…

java计算机毕业设计-游戏账号交易平台-演示录像-源程序+mysql+系统+lw文档+远程调试

java计算机毕业设计-游戏账号交易平台-演示录像-源程序mysql系统lw文档远程调试 java计算机毕业设计-游戏账号交易平台-演示录像-源程序mysql系统lw文档远程调试本源码技术栈&#xff1a; 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 开发软件&#xff1a;id…

基于复合粒子群优化的模糊神经预测控制的研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

【Python教学】pyqt6入门到入土系列,超详细教学讲解

一、什么是PyQt6? 简单介绍一下PyQt6 1、基础简介 PyQt6 Digia 公司的 Qt 程序的 Python 中间件。Qt库是最强大的GUI库之一。PyQt6的官网&#xff1a;www.riverbankcomputing.co.uk/news。PyQt6是由Riverbank Computing公司开发的 资料大礼包点击蓝色字体领取 Python零基础…

靶向嵌合体PEG-ethoxycarbonyl-propanoic/Dodecaethylene glycol

蛋白水解靶向嵌合体(proteolysis targeting chimeras,PROTACs)通过连接基团将靶蛋白配体与E3连接酶配体利用化学键连接,将E3连接酶“募集”到靶蛋白附近,并利用细胞内的泛素-蛋白酶体系统,实现靶蛋白的泛素化标记和蛋白降解。靶蛋白一旦被降解,PROTACs分子便游离出来,参与到下一…

【SpringBoot项目中Knife4j在线API文档】

目录 1. Knife4j在线API文档基本使用 2. 配置API文档信息 1. Knife4j在线API文档基本使用 Knife4j是一款基于Swagger 2的在线API文档框架。 使用Knife4j的基础步骤&#xff1a; 添加依赖在application.properties / application.yml中添加配置在项目中添加配置类关于依赖项…

互联网企业面试必问 Spring 源码? 拿下Spring 源码,看完这篇就够了

前言 不用说&#xff0c;Spring 已经成为 Java 后端开发的事实上的行业标准。无数公司选择 Spring 作为基本开发框架。大多数 Java 后端程序员在日常工作中也会接触到 Spring。因此&#xff0c;如何很好地使用 Spring&#xff0c;已成为 Java 程序员的必修课之一。 同时&…

cmd命令以及一些操作

文章目录前言set和echoif语句判断有无指定文件夹相对路径创建文件夹创建bat脚本换行符前言 因为下载下来的代码用bash脚本写的&#xff0c;cmd不能完美运行&#xff0c;因此想着对照着转成cmd&#xff0c;这样就方便了。 set和echo set demohello world!!! echo %demo%这就是…