偏序专题

https://www.luogu.com.cn/problem/P2163

很容易想到二维前缀和 但是因为数据范围是不允许的 就和之前校赛的题目一模一样

做这个题目前先看一下这个题目

只要将查询的点分为四个点 放入扫描数组中 再从小到大扫描一遍即可

#include<bits/stdc++.h>
#define reg register
using namespace std;
int n;
int c[2500005];
struct star{
    int x,y;
    int pos;//pos用来方便统计答案与判定是否为虚点
};
star st[2500005];
int ans[500005][5];
int tot[500005];
int x1_[500005],x2_[500005],y1_[500005],y2_[500005];//不要轻易用x1,x2,y1,y2...
int b[2500005],p;
bool cmp(star x,star y)
{
    if(x.x!=y.x)return x.x<y.x;
    if(x.y!=y.y)return x.y<y.y;
    return x.pos<y.pos;
}
inline void add(int x,int y)
{
    for(reg int i=x;i<=n;i+=i&-i)c[i]+=y;
}
inline int ask(int x)
{
    int ans=0;
    for(reg int i=x;i>=1;i-=i&-i)ans+=c[i];
    return ans;
}
inline int lsh(int x)
{
	return lower_bound(b+1,b+p+1,x)-b;
}
int main()
{
	//printf("%d",sizeof(ans)/1024/1024);
	int m;
    scanf("%d%d",&n,&m);
    if(n==0){
    	for(reg int i=1;i<=m;i++)printf("0\n");
    	return 0;
    }
    if(m==0)
    {
        return 0;
    }
    for(reg int i=1;i<=n;i++)scanf("%d%d",&st[i].x,&st[i].y),st[i].pos=0;
    for(reg int i=1;i<=m;i++){
    	scanf("%d%d%d%d",&x1_[i],&y1_[i],&x2_[i],&y2_[i]),st[++n].x=x1_[i]-1,st[n].y=y1_[i]-1,st[n].pos=i;
		st[++n].x=x2_[i],st[n].y=y2_[i],st[n].pos=i;
		st[++n].x=x2_[i],st[n].y=y1_[i]-1,st[n].pos=i;
		st[++n].y=y2_[i],st[n].x=x1_[i]-1,st[n].pos=i;
    }
    sort(st+1,st+n+1,cmp);
    for(reg int i=1;i<=n;i++)b[i]=st[i].y;
    sort(b+1,b+n+1);
    p=unique(b+1,b+n+1)-(b+1);
    for(reg int i=1;i<=n;i++)
    {
    	if(st[i].pos)ans[st[i].pos][++tot[st[i].pos]]=ask(lsh(st[i].y));
    	//printf("%d\n",ask(lsh(st[i].y)));
    	else if(st[i].pos==0)add(lsh(st[i].y),1);
		//printf("st[i].y=%d,ask(st[i].y)=%d\n",lsh(st[i].y),ask(st[i].y));
    }
    for(reg int i=1;i<=m;i++)
      printf("%d\n",ans[i][4]-ans[i][3]-ans[i][2]+ans[i][1]);
    return 0;
}

https://codeforces.com/problemset/problem/1320/C

和上题目思路大致相同 先将一维顺序化 因为维护最大值和区间修改 所以第二维用线段树维护

只需要在当前 [y+1,maxn] 这个区间上加上这个点的贡献就可以了

#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>

#define LL long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair

const double eps = 1e-10;
const int maxn = 1e6 + 1;
const LL mod = 1e9 + 7;
const LL INF = 1e18;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

struct segment_tree {
    LL val;
    int lazy;
}tree[maxn << 2];

LL a[maxn],b[maxn];
vector<pii> vec[maxn];

void build (int l,int r,int nod) {
    if (l == r) {
        tree[nod].val = -b[l];
        return ;
    }
    int mid = (l + r ) >> 1;
    build(l,mid,ls);
    build(mid+1,r,rs);
    tree[nod].val = max(tree[ls].val,tree[rs].val);
}

void pushdown(int nod) {
    tree[ls].lazy += tree[nod].lazy;
    tree[rs].lazy += tree[nod].lazy;
    tree[ls].val += tree[nod].lazy;
    tree[rs].val += tree[nod].lazy;
    tree[nod].lazy = 0;
}

void modify(int l,int r,int ql,int qr,int k,int nod) {
    if (ql <= l && qr >= r) {
        tree[nod].lazy += k;
        tree[nod].val +=  k;
        return ;
    }
    if (tree[nod].lazy)
        pushdown(nod);
    int mid = (l + r) >> 1;
    if (ql <= mid)
        modify(l,mid,ql,qr,k,ls);
    if (qr > mid)
        modify(mid+1,r,ql,qr,k,rs);
    tree[nod].val = max(tree[ls].val,tree[rs].val);
}


LL query(int l,int r,int ql,int qr,int nod) {
    if (ql <= l && qr >= r)
        return tree[nod].val;
    if (tree[nod].lazy)
        pushdown(nod);
    int mid = (l + r ) >> 1;
    LL ans = 0;
    if (ql <= mid)
        ans += query(l,mid,ql,qr,ls);
    if (qr > mid)
        ans += query(mid+1,r,ql,qr,rs);
    return ans;
}

int main() {
    for (int i = 0;i <= maxn;i++)
        a[i] = b[i] = INF;
    int n,m,p;
    cin >> n >> m >> p;
    for (int i = 1;i <= n;i++) {
        int x;
        LL y;
        cin >> x >> y;
        a[x] = min(a[x],y);
    }
    for (int i = 1;i <= m;i++) {
        int x;
        LL y;
        cin >> x >> y;
        b[x] = min(b[x],y);
    }
    for (int i = 1;i <= p;i++) {
        int x,y,z;
        cin >> x >> y >> z;
        vec[x].push_back(mp(y,z));
    }
    build(1,maxn,1);
    LL ans = -INF;
    for (int i = 1;i <= maxn;i++) {
        ans = max(ans,tree[1].val-a[i]);
        for (pii o : vec[i]) {
            if (o.first+1 < maxn)
                modify(1,maxn,o.first+1,maxn,o.second,1);
        }
    }
    cout << ans << endl;
    return 0;
}
posted @ 2022-08-06 11:55  wzx_believer  阅读(14)  评论(0编辑  收藏  举报