ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2018ICPC首尔A题 Circuits(线段树)

2020-12-17 15:01:07  阅读:283  来源: 互联网

标签:end Circuits 线段 tr 2018ICPC int 枚举 num


经典套路,首先发现只有两个边,这种情况下,很容易想到使用枚举的方法,枚举第一条边,然后计算对应的第二边最优,之后对于所有情况取max

这里只有y有用并且每个矩形其实就是一条线段

对于这题,一个需要考虑的问题是,如何当我们枚举一条边的时候,计算第二边答案的时候不会计算进第一条已经穿过的矩形。

那么其实这也是另一个套路,只要我们动态加边,倒着枚举,枚举每个点时,线段树中只有后面不会被当前点穿过的边,然后再维护一个前缀和,表示每个点能穿过的边

两个答案相加就是当前枚举点的答案

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=2e5+10;
vector<int> num;
vector<int> g[N];
int l[N],r[N];
int sum[N];
struct node{
    int l,r;
    int mx;
    int lazy;
}tr[N<<2];
int find(int x){
    return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
}
void build(int u,int l,int r){
    if(l==r){
        tr[u]={l,r};
    }
    else{
        tr[u]={l,r};
        int mid=l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
    }
}
void pushdown(int u){
    int x=tr[u].lazy;
    tr[u<<1].mx+=x;
    tr[u<<1|1].mx+=x;
    tr[u<<1].lazy+=x;
    tr[u<<1|1].lazy+=x;
    tr[u].lazy=0;
}
void pushup(int u){
    tr[u].mx=max(tr[u<<1].mx,tr[u<<1|1].mx);
}
void modify(int u,int l,int r,int x){
    if(tr[u].l>=l&&tr[u].r<=r){
        tr[u].mx+=x;
        tr[u].lazy+=x;
        return ;
    }
    if(tr[u].lazy)
        pushdown(u);
    int mid=tr[u].l+tr[u].r>>1;
    if(l<=mid)
        modify(u<<1,l,r,x);
    if(r>mid)
        modify(u<<1|1,l,r,x);
    pushup(u);
}
int main(){
    int n;
    ios::sync_with_stdio(false);
    cin>>n;
    int i;
    for(i=1;i<=n;i++){
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        l[i]=d,r[i]=b;
        num.push_back(b);
        num.push_back(d);
    }
    sort(num.begin(),num.end());
    num.erase(unique(num.begin(),num.end()),num.end());
    for(i=1;i<=n;i++){
        l[i]=find(l[i]);
        r[i]=find(r[i]);
        g[l[i]].push_back(r[i]);
        sum[l[i]]++,sum[r[i]+1]--;
    }
    for(i=1;i<=(int)num.size();i++){
        sum[i]+=sum[i-1];
    }
    int ans=0;
    build(1,1,(int)num.size());
    for(i=(int)num.size();i>=1;i--){
        ans=max(ans,sum[i]+tr[1].mx);
        for(auto x:g[i]){
            modify(1,i,x,1);
        }
    }
    cout<<ans<<endl;
}
View Code

 

标签:end,Circuits,线段,tr,2018ICPC,int,枚举,num
来源: https://www.cnblogs.com/ctyakwf/p/14149686.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有