首页 > 其他分享 >「JOISC 2019 Day4」蛋糕拼接 3 题解

「JOISC 2019 Day4」蛋糕拼接 3 题解

时间:2023-07-18 21:11:58浏览次数:43  
标签:rs int 题解 Day4 tr mid JOISC sum dp

先考虑这个式子:

\(\sum_{j=1}^{M} |C_{k_{j}} - C_{k_{j+1}}|\)

一定是在 \(C\) 有序时取到,具体证明很简单各位读者自己证明。

那么现在式子变成:

\(\sum{V} + 2 \times({C_{\max} - C_{\min}})\)

这个时候一个常见的技巧是将 \(C\) 排序。

这个时候就可以定义状态:

\(dp_{i,j} = \sum{V} + 2 \times (C_{j} - C_{i})\)

然后从贪心的思想出发,\(V\) 一定是选取区间 \([i,j]\) 中最大的 \(M\) 个。

令 \(f(i,j)\) 表示区间 \([i,j]\) 中前 \(M\) 大之和,有:

\(dp_{i,j} = f(i,j) + 2 \times (C_{j} - C_{i})\)

考虑去掉一维状态:

\(dp_{i} = \max{(f(i,j) + 2 \times C_{j})} - 2 \times C_i\)

因为 \(f(i,j) + 2 \times C_{j}\) 满足四边形不等式,所以 \(dp_{i}\) 满足决策单调性,考虑分治优化,\(f(i,j)\) 可以直接用主席树求解。

那么我们就 \(O(n \log^2 n)\) 地做完了。

#include<bits/stdc++.h>
#define int long long
using namespace std;
//dp[l][r] 表示区间 [l,r] 内前 M 大
//求 max(dp[l][r])
//max_{r>l}(dp[l][r])
//设计状态 dp[i] 表示区间 [i,j] 前 M 大之和减去 2*(c[j]-c[i]) 
//dp[i]=max{f(i,j)-2*c[j]}+2*c[i]
const int maxn = 2e5+114;
const int top = 1e9+114;
const int inf = 2e18+114514;
int dp[maxn];
int n,m;
struct Node{
    int sum,ls,rs;
	int val;
}tr[maxn*35];
struct hhx{
	int c,v;
}a[maxn];
int root[maxn],tot;
inline int kth(int lt,int rt,int L,int R,int k){
    if(lt==rt){
    	return k*lt;
	}
    int mid=(lt+rt)>>1;
    if((tr[tr[R].rs].sum-tr[tr[L].rs].sum)>=k){
        return kth(mid+1,rt,tr[L].rs,tr[R].rs,k);
    }
    else{
        return (tr[tr[R].rs].val-tr[tr[L].rs].val)+kth(lt,mid,tr[L].ls,tr[R].ls,k-(tr[tr[R].rs].sum-tr[tr[L].rs].sum));
    }
}
inline void add(int cur,int lst,int lt,int rt,int pos){
    tr[cur].sum=tr[lst].sum+1;
    tr[cur].val=tr[lst].val+pos;
    if(lt==rt){
        return ;
    }
    int mid=(lt+rt)>>1;
    if(pos<=mid){
        tr[cur].rs=tr[lst].rs;
        tr[cur].ls=++tot;
        add(tr[cur].ls,tr[lst].ls,lt,mid,pos);
    }
    else{
        tr[cur].ls=tr[lst].ls;
        tr[cur].rs=++tot;
        add(tr[cur].rs,tr[lst].rs,mid+1,rt,pos);
    }
}
//前 k 大之和 
void solve(int l,int r,int L,int R){
	if(l>r) return ;
	int mid=(l+r)>>1;
	int mx=-inf,p=0;
	for(int i=max(mid+m-1,L);i<=R;i++){
		if(kth(1,top,root[mid-1],root[i],m)-2*a[i].c>mx){
			mx=kth(1,top,root[mid-1],root[i],m)-2*a[i].c;
			p=i;
		}
	}
	dp[mid]=mx+2*a[mid].c;
	solve(l,mid-1,L,p);
	solve(mid+1,r,p,R);
}
bool cmp(hhx A,hhx B){
	return A.c<B.c;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++) dp[i]=-inf;
	for(int i=1;i<=n;i++) cin>>a[i].v>>a[i].c;
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++){
		root[i]=++tot;
		add(root[i],root[i-1],1,top,a[i].v);
	}
	solve(1,n-m+1,1,n);
	int ans=-inf;
	for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
	cout<<ans;
}

标签:rs,int,题解,Day4,tr,mid,JOISC,sum,dp
From: https://www.cnblogs.com/chifan-duck/p/17564139.html

相关文章

  • Python基础day47
    img标签图片,在网页显示图片的标签会有属性: 1.自带的属性2.自定义的属性<imgsrc="img/123.png"alt="你看我是什么东西"width="800px"height="200px">src:写图片的地址1.外链地址2.相对地址alt: 当图片地址加载失败的时候,显示的描述性信......
  • CF1438F 题解
    problem&blog。神秘随机题。众所周知:\((u,v)\)的LCA是所有点\(i\)中\(\operatorname{dis}(u,i)+\operatorname{dis}(v,i)+\operatorname{dis}(\text{root},i)\)最小的。对于一个点\(u\),设其有两个子树\(T_1,T_2\),它能作为LCA的方案数是\(|T_1|\times|T_2|\ti......
  • CF1769C2 Подкрутка II 题解
    看到同机房的好哥们发了贪心做法的题解,心血来潮就A了这道题写了真·dp的题解。虽然方法比老师上课讲的麻烦的多,并不是最优解,但至少是我自己思考得出的结果。题目要求输入一个原序列\(a_i\),从\(a_i\)中求得某个区间\([l,r]\)。此区间经过题面中所描述的修改操作(任何元素\(......
  • P6835 [Cnoi2020] 线形生物题解
    P6835[Cnoi2020]线形生物题解题目描述求从\(1\)到\(n+1\)的链的期望,其中有\(m\)条返祖边:\(u->v\)这条边\(u\gev\),等概率,求期望Solution这种爬楼梯的题一般求解\(E(x\rightarrowx+1)\),则最后答案为\(\sum_{i=1}^nE(i\rightarrowi+1)\)我们考虑从\(x\rightarr......
  • Building Bridges 题解
    BuildingBridges题目大意连接两根柱子\(i,j\)的代价是\((h_i-h_j)^2+\sum\limits_{k=j+1}^{i-1}w_k\),连接具有传递性,求将\(1,n\)连接的最小代价。思路分析斜率优化DP板题。设\(f_i\)表示考虑到前\(i\)根柱子并强制选择第\(i\)根柱子的最小代价,所求即\(f_n\)。......
  • [ABC310D] Peaceful Teams 题解
    PeacefulTeams题目大意将\(n\)个人分成\(T\)组,要求每组不能包含敌对的人,问有多少种分法。思路分析注意到\(n,T\)均很小,考虑爆搜。注意到直接枚举会枚举到分组顺序的全排列,所以可以强行嵌定大小关系去重。voiddfs(ints){if(s==n+1){for(inti=1;i<=t;......
  • NOI春季测试前模拟赛题解
    T312819命题工作直接容斥。总方案-一题出现四次-一题出现三次-一题出现两次。一题出现两次的情况略有不同,注意考虑周全。复杂度\(O(n)\)。codeT312891图上棋局有技巧的博弈论。如果当前点的所有出边均为先手必胜,那么当前点为先手必败。否则先手必胜。于是......
  • 题解 P2137 Gty的妹子树
    神奇的分块。假如没有\(2\)操作,我们可以直接用主席树解决。我们考虑将询问分块,每遍历完一块就将这一块内出现的所有修改更新。如果在块内,就把当前块之前的所有修改暴力算,当然只有修改的节点在询问的节点的子树内才会发生。具体的来说,我们可以用分块维护dfs序,并将块内的元素......
  • 题解 P4183 [USACO18JAN] Cow at Large P
    带有小trick的点分治。建议先做完弱化版再看。假如奶牛在\(u\),那么所需的最少农夫数为\(\sum\limits_{v\inson(u)}[dis(u,v)\geg_v][dis(u,fa_v)<g_{fa_v}]\)。其中\(dis(u,v)\)为\(u,v\)在树上的距离,\(g_u\)为\(u\)到离它最近的出入口的距离(BFS预处理),\(fa_u\)......
  • 题解 P9415 下楼
    不难推理出当初始绳长为\(len\),需要下降的距离为\(d\),并且满足\(d\lelen<2d\)时,最优的环套法可以只损失\(2d-len\)长度的绳子,留下\(2(len-d)\)的绳子。当\(2d\lelen\)时存在一种不损耗绳长的方法可以下到下一根钢管,即把整根绳子系成一个环,到达下面再剪断。正文:线......