Codeforces Round #625 Div1 C,二维偏序,排序+线段树

题目

题意:

有若干武器A,攻击力A1,费用A2,
有若干铠甲B,防御力B1,费用B2,
有若干怪兽M,攻击力M1,防御力M2,奖励M3
你可以选择一把武器,一个铠甲,打败所有攻击和防御都严格小的怪兽,问最大收益。

思路:

典型的二维偏序问题,把攻击和防御想象成二维的坐标轴,我们要找到的其实就是一个矩形里(0,0)~(x,y)里收益-这个矩形的花费的最大值。我们可以排序一维,另一维用线段树维护,枚举的时候往里面加怪兽就好。

代码:

#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define PB push_back
#define LL long long
#define pii pair<LL,LL>
#define MEM(x,y) memset(x,y,sizeof(x))
#define bug(x) cout<<"debug "#x" is "<<x<<endl;
#define FIO ios::sync_with_stdio(false);
#define ALL(x) x.begin(),x.end()
#define LOG 20
#define lson(x) ((x)<<1)
#define rson(x) ((x)<<1|1)
const int maxn=5e6;
const LL inf = 2e9;
int N = 1e6;
LL n,m,P,sum[maxn],lazy[maxn];
pii A[maxn],B[maxn];
pair<int,pii> MO[maxn];
void push_down(int p){
    lazy[lson(p)]+=lazy[p];
    lazy[rson(p)]+=lazy[p];
    lazy[p]=0;
}
void modify(int tr,int l,int r,int L,int R,int v){
    if(r<L||l>R)return;
    if(L<=l&&r<=R){
        lazy[tr]+=v;
        return;
    }
    push_down(tr);
    int mid=(l+r)/2;
    modify(rson(tr),mid+1,r,L,R,v);
    modify(lson(tr),l,mid,L,R,v);
    sum[tr]=max(sum[lson(tr)]+lazy[lson(tr)],sum[rson(tr)]+lazy[rson(tr)]);
    return ;
}
int main(){
    FIO;
    LL ans= -inf;
    cin>>n>>m>>P;
    for(int i=1;i<=n;i++) cin>>A[i].X>>A[i].Y;
    for(int i=1;i<=m;i++) cin>>B[i].X >>B[i].Y;
    for(int i=1;i<=P;i++) cin>>MO[i].X >>MO[i].Y.X >>MO[i].Y.Y;
    sort(MO+1,MO+P+1);
    sort(A+1,A+n+1);
    sort(B+1,B+m+1);
    MEM(lazy,0);MEM(sum,0);
    N = m;
    for(int i=1;i<=m;i++) modify(1,1,N,i,i,-B[i].Y);
    for(int idx=1,i=1;i<=n;i++){
        while(MO[idx].X<A[i].X&&idx<=P){
            int it = upper_bound(B+1,B+1+m,make_pair(MO[idx].Y.X,inf)) - B;
            if(it<=N)modify(1,1,N,it,N,MO[idx].Y.Y);
            idx++;
        }
        ans=max(ans,sum[1]+lazy[1]-A[i].Y);
    }
    cout<<ans<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/zhangxianlong/p/12411362.html

时间: 2024-08-30 07:02:00

Codeforces Round #625 Div1 C,二维偏序,排序+线段树的相关文章

[Codeforces Round #444 div1] C.DZY Loves Colors 【线段树】

题目链接:CF Round #444 div1 C 题目分析 这道题目是要实现区间赋值的操作,同时还要根据区间中原先的值修改区间上的属性权值. 如果直接使用普通的线段树区间赋值的方法,当一个节点表示的区间完全被要求修改的区间包含时,就直接打上赋值的标记然后 return .但是这样这个节点中每个位置原先的值不同,需要进行的属性权值修改也就不同,是不能直接实现的.如果我们在节点表示的区间被修改的区间包含时,并不直接打标记 return ,而是当节点表示的区间被修改的区间完全包含而且这个节点中的每个

[luogu4479][BJWC2018]第k大斜率【二维偏序+二分+离散化+树状数组】

传送门 https://www.luogu.org/problemnew/show/P4479 题目描述 在平面直角坐标系上,有 n 个不同的点.任意两个不同的点确定了一条直线.请求出所有斜率存在的直线按斜率从大到小排序后,第 k 条直线的斜率为多少. 为了避免精度误差,请输出斜率向下取整后的结果.(例如: ?1.5? = 1 , ??1.5? = ?2 ) 分析 一开始打了一个暴力,10分后来改着改着成了30分,浮点误差. 正解其实很简单,我们首先逆向思考一下,如果我们假设已经有了斜率k. 如

Codeforces Round #578 (Div. 2) 二维差分 可做模板

题意: 在n*n的矩阵中,你可以选择一个k*k的子矩阵,然后将这个子矩阵中的所有B全部变为W,问你怎么选择这个子矩阵使得最终的矩阵中某一行全是W或者某一列全是W的个数最多 题解:考虑每一行和每一列,对于特定的一行来说,要想让其全变为W,那么子矩阵的左上角端点是在一个范围中的,因此我们可以把范围中的每一个值加1 为了速度选择用二维差分来做,最终矩阵中的最大值就是答案 此题可以作为二维差分模板 #include<bits/stdc++.h> #define forn(i, n) for (int

Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题是线段树成段更新,但是不能直接更新,不然只能一个数一个数更新.这样只能把每个数存到一个数组中,长度大概是20吧,然后模拟二进制的位操作.仔细一点就行了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath>

Codeforces Round #310 (Div. 1) C. Case of Chocolate (线段树)

题目地址:传送门 这题虽然是DIV1的C..但是挺简单的..只要用线段树分别维护一下横着和竖着的值就可以了,先离散化再维护.每次查找最大的最小值<=tmp的点,可以直接在线段树里搜,也可以二分去找. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.

Codeforces Round #207 (Div. 1) A. Knight Tournament (线段树离线)

题目:http://codeforces.com/problemset/problem/356/A 题意:首先给你n,m,代表有n个人还有m次描述,下面m行,每行l,r,x,代表l到r这个区间都被x所击败了(l<=x<=r),被击败的人立马退出游戏让你最后输出每个人是被谁击败的,最后那个胜利者没被 人击败就输出0 思路:他的每次修改的是一个区间的被击败的人,他而且只会记录第一次那个被击败的人,用线段树堕落标记的话他会记录最后一次的,所以我们倒着来修改, 然后因为那个区间里面还包含了自己,在线段

Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)

链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowercase Latin letters and q queries for this string. Recall that the substring s[l;r] of the string s is the string slsl+1-sr. For example, the substrings

Codeforces Round #225 (Div. 2)---E. Propagating tree(时间戳+线段树)

Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numbered from 1 to n, each node i having an initial value ai. The root of the tree is node 1. This tree has a special propert

Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并

D. Vika and Segments Vika has an infinite sheet of squared paper. Initially all squares are white. She introduced a two-dimensional coordinate system on this sheet and drew n black horizontal and vertical segments parallel to the coordinate axes. All