蚯蚓

蚯蚓1

被刻印的时光 ゝ 提交于 2020-02-16 17:40:44
本题中,我们将用符号⌊c⌋ 表示对 c 向下取整,例如:⌊3.0⌋=⌊3.1⌋=⌊3.9⌋=3。 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓。 蛐蛐国里现在共有 n 只蚯蚓(n 为正整数)。每只蚯蚓拥有长度,我们设第 i 只蚯蚓的长度为ai,并保证所有的长度都是非负整数(即:可能存在长度为 0 的蚯蚓)。 每一秒,神刀手会在所有的蚯蚓中,准确地找到最长的那一只(如有多个则任选一个)将其切成两半。神刀手切开蚯蚓的位置由常数 p(是满足0<p<1 的有理数)决定,设这只蚯蚓长度为 x,神刀手会将其切成两只长度分别为 ⌊px⌋ 和 x−⌊px⌋ 的蚯蚓。特殊地,如果这两个数的其中一个等于 0,则这个长度为 0 的蚯蚓也会被保留。此外,除了刚刚产生的两只新蚯蚓,其余蚯蚓的长度都会增加 q(是一个非负整常数)。 蛐蛐国王知道这样不是长久之计,因为蚯蚓不仅会越来越多,还会越来越长。蛐蛐国王决定求助于一位有着洪荒之力的神秘人物,但是救兵还需要 m 秒才能到来……(m 为非负整数) 蛐蛐国王希望知道这 m秒内的战况。具体来说,他希望知道: m 秒内,每一秒被切断的蚯蚓被切断前的长度(有 m 个数);m 秒后,所有蚯蚓的长度(有 n+m 个数)。 蛐蛐国王当然知道怎么做啦!但是他想考考你…… 输入格式 第一行包含六个整数 n,m,q,u,v,t

P2827 蚯蚓

匿名 (未验证) 提交于 2019-12-03 00:05:01
题面: https://www.luogu.org/problem/P2827 本题首先可以发现先被切掉的蚯蚓分成的蚯蚓一定比后切掉的蚯蚓分成的蚯蚓大. 假设这两只蚯蚓分别为 a , b ,其中 a > b .那么它被切成 a1 , a2 t 秒后, b 被切成了 b1 , b2 .此时 a1 , a2 p * la + t ,( 1 p )* la + t 而 b1 , b2 的长度为 p ( lb + t ),( 1 p )( lb + t ), 显然 la1 > lb1 , la2 > lb2 ,也就是说: 如果有蚯蚓 a1 , a2 an 满足 a1 > a2 an ,那么以此分成两只 a11 , a12 , a21 , a22 an1 , an2 , 那么就有 a11 > a21 an1 , a12 > a22 an2 那么就可以将这两堆依次存储, 加上还没被切过的蚯蚓.每次要切时在这三堆里面选择最大的, 切完再依次放回去即可. 时间复杂度为 O ( m ) Code : #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> using namespace std ; const int N = 7000005 ; int n , m ,

洛谷p2827蚯蚓题解

不想你离开。 提交于 2019-12-01 07:23:43
题目 算法标签里的算法什么的都不会啊 什么二叉堆?? qbxt出去学习的时候讲的,一段时间之前做的,现在才写到博客上的 维护3个队列,队列1表示最开始的蚯蚓,队列2表示每一次被切的蚯蚓被分开的较长的那一部分,队列3表示每一次被切的蚯蚓被分开的较短的那一部分。 我们先把原序列排序,因为不管怎么切,先被切的蚯蚓分成的两部分一定比后切的蚯蚓分成的两部分大 寻找每次切哪一只蚯蚓就是在队列1、队列2、队列3的队头找一个算上增加的长度最大的蚯蚓,之后把他出队,切开的两部分分别进入队2、队3。 最后合并输出 Code: #include <queue> #include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int N = 10000010; unsigned long long n, m, q, u, v, a[N], ans[N], s, y, tot, t; queue<int>q1, q2, q3; int cmp (long x, long y) { return x > y; } int maxn () { long long x1 = -(1 << 30), x2 = x1, x3 = x1; if (!q1.empty ()) x1 = q1.front ();

切蚯蚓

可紊 提交于 2019-11-30 19:37:29
题目链接 时隔一年多,终于A掉了... 错因: 1.用第二行的写法就会错。(可以不用 \(floor\) ) 2.因为队列中的元素需要加上时间戳才是真实的长度,所以会有负的,假如队列一为空,队列二和队列三里的元素都为负,就会取到空队列里的0元素(因为手写的队列,不会 \(CE\) )。 被这么两个小点卡死了www #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<queue> using namespace std; const int N = 7000005; const int inf = 1e9+7; int q1[N],q2[N],q3[N],ad; //priority_queue<int>ans; int ans[N<<1]; int h1,t1,h2=1,t2,h3=1,t3; int n,m,u,v,p,q,t; bool cmp(int a,int b) { return a>b;} double val; int main() { // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t); val=

P2827 蚯蚓

自闭症网瘾萝莉.ら 提交于 2019-11-29 22:39:17
嘿嘿题目链接 首先我们给蚯蚓从大到小排序。然后可以发现,每次切出来的蚯蚓中,长的那写按切的顺序形成非上升序列,短的那些也如此。那么我们维护3个单调队列即可(原始蚯蚓也算一个单调队列),每次找三个队列队首元素最大的那个,把这个蚯蚓切掉,然后分别插入两个单调队列中。最后也按照这样每次找出最大的,按要求把该输出的输出即可。由于最后有n+m只蚯蚓,所以这样的时间复杂度O(n+m)。 1 #include<set> 2 #include<map> 3 #include<list> 4 #include<queue> 5 #include<stack> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<vector> 10 #include<bitset> 11 #include<memory> 12 #include<utility> 13 #include<cstdio> 14 #include<sstream> 15 #include<iostream> 16 #include<cstdlib> 17 #include<cstring> 18 #include<algorithm> 19 using namespace std; 20 21 int n,m,q,u,v,g,del; 22 long long

$Noip2016/Luogu2827$蚯蚓

只愿长相守 提交于 2019-11-28 12:59:39
$Luogu$ $Sol$ 乍一看就是个模拟叭,用个优先队列维护不就好了.不过这里有一个问题就是怎么解决没被切的蚯蚓的增长问题.可以这样处理,每次切一条蚯蚓,给切完之后的都减去$q$,最后输出答案时都加上$q*m$就$OK$辣.还有一个要注意的地方就是每次切蚯蚓的时候都要求出它的实际长度而不是存在优先队列里的长度. 但是这样只有$80$的样子.瞎分析一波复杂度似乎是$O(mlog_{n+m}^2)$. 考虑优化,如果能把这个$log^2$去掉就好了吖. 注意到,先被切的蚯蚓的较长的一段一定大于后被切的蚯蚓的较长的一段,先被切的蚯蚓的较短的一段一定大于后被切的较短的一段.于是不需要优先队列就可以维护单调性了.具体来说开三个数组,分别存还没被切的蚯蚓(初始数组,记得排序),被切了之后较长的那个蚯蚓,被切之后较短的蚯蚓.每次选取三个数组里最长的那个切,切完之后分别加入后面两个数组就好了不需要多余的维护. $Code$ #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<cmath> using namespace std; int r() { int x=0,y=1;;char ch; ch=getchar(); while(ch<'0'|

[NOIP2016]蚯蚓(单调性乱搞)

一曲冷凌霜 提交于 2019-11-27 05:36:34
题目 链接 思路 最简单的思路肯定就是直接用堆维护,每次取最大的那一个,切成两截扔回堆里面(至于所有蚯蚓加上 \(q\) ,可以看做是新生成的蚯蚓减去 \(time*q\) ,最后再加回去即可,其中 \(time\) 即第几秒),然而这样子做是 \(O(n+m)log(n+m)\) 的,过不了 分析后可以发现单调性,即如果把切出来的两部分分别放到一个数组里面,它们分别单调递减 证明也很简单,设先切的蚯蚓长度为 \(len1\) ,后切的在切 \(len1\) 的这个时候长度为 \(len2\) ,那么有 \(len2\) \(\leq\) \(len1\) ,它们长度不增长的时间仅仅是切的时候,即它们的增加量相等,那么有 \(len2+c\) \(\leq\) \(len1+c\) 恒成立 所以把它们分成三个数组(队列),分别存初始蚯蚓、(切了一刀之后)第一节、第二节,对初始蚯蚓排序可以使第一个数组从大到小排序,将后切出来的蚯蚓放到队列后面可以使得这两个数组也满足从大到小排序,取最大的蚯蚓即从三个队列的队头取最大值 对于第二问,将三个队列进行归并排序即可 时间复杂度为 \(O(nlogn+m)\) #include<bits/stdc++.h> #define N 100005 #define M 7000005 using namespace std; int n,m,q,u,v

AcWing 蚯蚓

左心房为你撑大大i 提交于 2019-11-26 11:11:31
AcWing 蚯蚓 Description 蛐蛐国最近蚯蚓成灾了! 隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓。 蛐蛐国里现在共有 n 只蚯蚓,第 i 只蚯蚓的长度为 ai ,所有蚯蚓的长度都是非负整数,即可能存在长度为0的蚯蚓。 每一秒,神刀手会在所有的蚯蚓中,准确地找到最长的那一只,将其切成两段。若有多只最长的,则任选一只。神刀手切开蚯蚓的位置由有理数 p 决定。 一只长度为 x 的蚯蚓会被切成两只长度分别为 ⌊px⌋ 和 x−⌊px⌋ 的蚯蚓。 特殊地,如果这两个数的其中一个等于0,则这个长度为0的蚯蚓也会被保留。 此外,除了刚刚产生的两只新蚯蚓,其余蚯蚓的长度都会增加一个非负整数 q 。 蛐蛐国王知道这样不是长久之计,因为蚯蚓不仅会越来越多,还会越来越长。 蛐蛐国王决定求助于一位有着洪荒之力的神秘人物,但是救兵还需要 m 秒才能到来。 蛐蛐国王希望知道这 m 秒内的战况。 具体来说,他希望知道: m 秒内,每一秒被切断的蚯蚓被切断前的长度,共有 m 个数。 m 秒后,所有蚯蚓的长度,共有 n+m 个数。 Input 第一行包含六个整数 n,m,q,u,v,t,其中:n,m,q 的意义参考题目描述;u,v,t 均为正整数;你需要自己计算 p=u/v(保证 0<u<v);t 是输出参数,其含义将会在输出格式中解释。 第二行包含 n 个非负整数,为