解题:九省联考2018 IIIDX

题面

我当时在考场上划水的时候好像乱搞搞了20pts,然后发现一堆同届的都写了55pts的贪心=。=???

那就先说那55pts的贪心吧,这个现在看起来还是非常显然的,就是按题意来每一块是分属一个点的,其实这就是棵树,排序之后从叶子往上递增地放就可以了,挺送的=。=

为什么错了,显然有相同的数的时候可能把一个大点的数放前面也是对的,然后就不优了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=500005,M=2e6+20;
 6 int val[N],fth[N],siz[N],lst[N];
 7 int n,minn[M],laz[M],rnk[N];
 8 double k;
 9 bool cmp(int x,int y)
10 {
11     return x>y;
12 }
13 void Release(int nde)
14 {
15     if(laz[nde])
16     {
17         int ls=2*nde,rs=2*nde+1;
18         minn[ls]+=laz[nde],minn[rs]+=laz[nde];
19         laz[ls]+=laz[nde],laz[rs]+=laz[nde],laz[nde]=0;
20     }
21 }
22 void Create(int nde,int l,int r)
23 {
24     if(l==r)
25         minn[nde]=l;
26     else
27     {
28         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
29         Create(ls,l,mid),Create(rs,mid+1,r);
30         minn[nde]=min(minn[ls],minn[rs]);
31     }
32 }
33 void Change(int nde,int l,int r,int ll,int rr,int tsk)
34 {
35     if(l>rr||r<ll)
36         return ;
37     else if(l>=ll&&r<=rr)
38         minn[nde]+=tsk,laz[nde]+=tsk;
39     else
40     {
41         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde);
42         Change(ls,l,mid,ll,rr,tsk),Change(rs,mid+1,r,ll,rr,tsk);
43         minn[nde]=min(minn[ls],minn[rs]);
44     }
45 }
46 int Query(int nde,int l,int r,int tsk)
47 {
48     if(l==r)
49         return l+(tsk>minn[nde]);
50     else
51     {
52         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde);
53         return (tsk<=minn[rs])?Query(ls,l,mid,tsk):Query(rs,mid+1,r,tsk);
54     }
55 }
56 int main()
57 {
58     scanf("%d%lf",&n,&k);
59     for(int i=1;i<=n;i++)
60         scanf("%d",&val[i]),siz[i]=1;
61     sort(val+1,val+1+n,cmp);
62     for(int i=n;i;i--)
63     {
64         fth[i]=1.0*i/k,siz[fth[i]]+=siz[i];
65         if(val[i]==val[i+1]) lst[i]=lst[i+1]+1;
66     }
67     Create(1,1,n);
68     for(int i=1;i<=n;i++)
69     {
70         if(fth[i]!=fth[i-1])
71             Change(1,1,n,rnk[fth[i]],n,siz[fth[i]]-1);
72         int ans=Query(1,1,n,siz[i]);
73         ans+=lst[ans],lst[ans]++,ans-=lst[ans]-1;
74         rnk[i]=ans,Change(1,1,n,ans,n,-siz[i]);
75     }
76     for(int i=1;i<=n;i++)
77         printf("%d ",val[rnk[i]]);
78     return 0;
79 }

原文地址:https://www.cnblogs.com/ydnhaha/p/10279005.html

时间: 2024-09-30 07:54:04

解题:九省联考2018 IIIDX的相关文章

[luogu] P4364 [九省联考2018]IIIDX(贪心)

P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI 内工作,离他的梦想也越来越近了. 这款音乐游戏内一般都包含了许多歌曲,歌曲越多,玩家越不易玩腻.同时,为了使玩家在游戏上氪更多的金钱花更多的时间,游戏一开始一般都不会将所有曲目公开,有些曲目你需要通关某首特定歌曲才会解锁,而且越晚解锁的曲目难度越高. 题目描述 这一天,Konano 接到了一个任务

[九省联考 2018]IIIDX

Description 题库链接 给你 \(n+1\) 个节点的一棵树,节点编号为 \(0\sim n\) , \(0\) 为根.边集为 \(\mathbb{E}=\left\{(u,v)\big|\forall i\in[1,n],\left(\left\lfloor\frac{i}{k}\right\rfloor,i\right)\right\}\) .给出 \(n\) 个待选序号,让你为 \(1\sim n\) 这 \(n\) 个节点编号,第 \(i\) 号节点编为 \(a_i\),要求父

[九省联考2018]IIIDX

传送门 形式化题意:一棵树,对于每个节点赋予一个给定的权值,使得每个节点都不大于子树内节点,同时满足编号小的点尽可能大. 首先在所有给定的数不同的时候只要贪心一次,从小到大把数排序,之后建树在上面跑dfs,按dfn从小到大给权值. 但是这样在有相同的数据的时候是会错的.因为有可能通过交换使得子树内节点权值和根相等.(例子在luogu讨论区有的) 我们重新考虑一下.把所有的数从大到小排序,记录\(C_i\)为每个点左边还能被使用的权值个数.这样的话每次找一个位置赋权值的话,其实就是找一个位置使得它

【BZOJ5248】【九省联考2018】一双木棋(搜索,哈希)

[BZOJ5248][九省联考2018]一双木棋(搜索,哈希) 题面 BZOJ Description 菲菲和牛牛在一块n行m列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手.棋局开始时,棋盘上没有任何棋子, 两人轮流在格子上落子,直到填满棋盘时结束.落子的规则是:一个格子可以落子当且仅当这个格子内没有棋子且 这个格子的左侧及上方的所有格子内都有棋子. 棋盘的每个格子上,都写有两个非负整数,从上到下第i行中从左到右第j列的格子上的两个整数记作Aij.Bij.在 游戏结束后,菲菲和牛牛会分别计算自己

九省联考 2018 游记

Day0:乘火车到了上海.明天就是激动人心的比赛啦 深夜和室友看<我在七年后等你>.这真是一款不错的手游,让人印象深刻啊 Day1:迷迷糊糊到了学校.编程环境是Win7?不太习惯啊. T1:一眼状压dp题. T2:肯定可以建成一棵树,然后直接贪心?不对啊,T2不应该这么水啊(开始怀疑) T3:乍一看怎么一点思路没有啊. 8:40~11:10:持续思考T3中. 11:10:终于有思路了!如果直接NTT向上dp的话,因为链的情况复杂度会不对,所以似乎可以树剖!用线段树分治和NTT处理重链上的dp!

解题:九省联考2018 秘密袭击CoaT

题面 按照*Miracle*的话来说,网上又多了一篇n^3暴力的题解 可能是因为很多猫上树问题虽然很好,但是正解性价比比较低? 我当时在考场上划水的时候手玩了5pts 直接做不可做,转化为统计贡献:$O(n)$枚举每个权值,直接统计第k大大于等于这个权值的联通块个数的和- -这样每个权值x恰会贡献x次. 将所有大于等于当前权值的点点权赋为1,其余点点权赋为零,然后就是$O(n^2)$树形背包:设$dp[i][j]$表示以i为根的子树里选出(新)点权和为j的联通块,且联通块必须包含i自身的方案数.

[BZOJ5251][九省联考2018]劈配(网络流)

5251: [2018多省省队联测]劈配 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 33  Solved: 22[Submit][Status][Discuss] Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 题目描述 轻车熟路的Zayid顺利地通过了海选,接下来的环节是导师盲选,这一阶段的规则是这样的: 总共n名参赛选手(编号

[BZOJ5248][九省联考2018]双木棋chess

bzoj luogu sol 首先,要保证一个格子的左边和上方都放满了棋子,就需要这个点的左上方那个矩形都放满了棋子. 这样放旗子状态就会是一个自左下至右上的轮廓线. 状态数? 跟\(yyb,ppl\)讨论了一下状态数理论上应该是\(C_{20}^{10}\)啊. 然而... #include<cstdio> #include<algorithm> using namespace std; int n,m,a[20],tot; void dfs(int u) { if (u==n+

[九省联考 2018]一双木棋chess

Description 题库链接 给出一个 \(n\times m\) 的棋盘,棋盘的每个格子有两个权值 \(A,B\) . Alice 和 Bob 轮流操作在棋盘上放棋子,一个格子能放棋子的前提条件是这个格子的左侧和上侧均放了棋子.对于 Alice 放棋子的格子,能获得该格子的 \(A\) 的权值:对于 Bob 放棋子的格子,能获得该格子的 \(B\) 的权值. Alice 想最大化得分差, Bob 想最小化得分差,求最后得分差. \(1\leq n,m\leq 10\) Solution 比