[BZOJ4700]适者 CDQ分治
来源:互联网 发布:java md5 编辑:程序博客网 时间:2024/06/16 14:59
看到题目以后并没有第一时间想到cdq分治,看了很多篇题解都没有明白,后来自己yy出来了一个解法,应该是对的反正过了
首先考虑若一个炮塔都没有被秒杀,那么怎么安排攻击顺序最好
对于两个炮塔u,v,若u在前那么v将多产生
当u在v前时,满足
再来考虑从中拿两个走,记拿x走总伤害减少
我们需要找到最大的
考虑对于每一个
即使得
可能说的有点抽象,给一下主程序的步骤:
1、递归处理左右区间
2、右区间按a[]排升序,即自变量从小到大
3、左区间加入单调队列
4、两个指针扫一下,把左区间的信息加到右区间上
5、整个区间按d[]排序,即按斜率排升序(注意这里斜率取负数)
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#define N 300050#define mid ((l + r) >> 1)#define INF (1LL<<62)using namespace std;typedef long long LL;struct Monster{ LL a,d,c,_; }x[N],tmp[N];int q[N],h,t,n,ATK;LL sum_d[N]; inline void ut(LL &x,LL y) { x = min(x,y); }inline int rd() { int r; scanf("%d",&r); return r; }bool cmp1(Monster p1,Monster p2) { return p1.d * p2.a < p2.d * p1.a;}bool cmp2(Monster p1,Monster p2) { return p1.a < p2.a; }void _sort1(int l,int r) { int p1 = l , p2 = mid+1 , cur = l-1; while (p1<mid && p2<r) { if (x[p1].a < x[p2].a) tmp[++cur] = x[p1] , p1++; else tmp[++cur] = x[p2] , p2++; } while (p1 <= mid) tmp[++cur] = x[p1] , p1++; while (p2 <= r) tmp[++cur] = x[p2] , p2++; for (int _=l;_<=r;_++) x[_] = tmp[_];}void _sort2(int l,int r) { int p1 = l , p2 = mid+1 , cur = l-1; while (p1<mid && p2<r) { if (x[p1].d < x[p2].d) tmp[++cur] = x[p1] , p1++; else tmp[++cur] = x[p2] , p2++; } while (p1 <= mid) tmp[++cur] = x[p1] , p1++; while (p2 <= r) tmp[++cur] = x[p2] , p2++; for (int _=l;_<=r;_++) x[_] = tmp[_];}inline LL calc(int p1,int p2) { return x[p1].c + x[p2].c + x[p1].d * x[p2].a;}void solve(int l,int r) { if (l == r) return ; solve(l,mid); solve(mid+1,r); _sort2(mid+1,r); q[h=t=1] = l; for (int i=l+1;i<=mid;i++) { while (h<=t && x[i].c > x[ q[t] ].c) t--; q[++t] = i; } for (int i=mid+1;i<=r;i++) { while (h<t && calc(q[h],i) < calc(q[h+1],i)) h++; x[i]._ = max( x[i]._ , calc(q[h],i) ); } _sort1(l,r);}//36+42+30int main() { #ifndef ONLINE_JUDGE freopen("1.in","r",stdin); #endif n = rd() , ATK = rd(); for (int i=1;i<=n;i++) x[i].a = rd() , x[i].d = rd() , x[i]._ = -INF; for (int i=1;i<=n;i++) x[i].d = (int) ceil( (double)x[i].d / (double)ATK ); sort(x+1,x+n+1,cmp1); LL cur = 0LL , sum = 0LL; for (int i=1;i<=n;i++) sum_d[i] = sum_d[i-1] + x[i].d; for (int i=n;i>=1;i--) { x[i].c = x[i].d * cur + x[i].a * (sum_d[i]-1); sum += x[i].d * cur + x[i].a * (x[i].d-1); cur += x[i].a; } //转成斜率 for (int i=1;i<=n;i++) x[i].d = -x[i].d;// sort(x+1,x+n+1,cmp2); solve(1,n); LL ans = INF; for (int i=1;i<=n;i++) ut(ans,sum-x[i]._); cout << ans << endl; return 0;}
0 0
- [BZOJ4700]适者 CDQ分治
- [bzoj4700]适者
- [bzoj4700]适者
- cdq分治
- cdq分治
- cdq分治
- cdq分治
- BZOJ4700
- BZOJ4700
- 时间分治(cdq分治)
- 学习笔记: cdq分治
- bsoj2653 cdq分治
- 【CDQ分治】数据
- BZOJ3262【CDQ分治】
- BZOJ1492【CDQ分治】
- CDQ分治优化DP
- HDU 4456 CDQ分治
- cdq分治模板
- mysql分表方法-----MRG_MyISAM引擎分表法
- Android Studio apk系统签名和版本描述的实现
- Kettle开发之常用步骤开发
- kubernetes源码解读——源码结构
- 解决json字符串转java bean 并包含日期且日期为空
- [BZOJ4700]适者 CDQ分治
- RDF自然语言查询技术
- 利用String类制作简单的网络爬虫
- android6.0下webview的定位权限设置
- Leetcode OJ: ZigZag Conversion
- Android开发直接调试后,删除有残留,带签名正式包装不上
- RDF关键词查询技术
- 大神推荐java多并发访问框架
- 功能实现-下载中心