码迷,mamicode.com
首页 > 其他好文 > 详细

CF500E New Year Domino(并查集+栈)

时间:2020-10-13 17:46:19      阅读:29      评论:0      收藏:0      [点我收藏+]

标签:bsp   lap   false   图片   覆盖   closed   end   none   std   

答案就是就是区间没有覆盖的长度

有一个直接的想法就是我们发现能够通过推倒建立起来的关系就是一个集合,也就是用并查集缩点,那么之后只需要维护一个后缀和就能做

因为我们不可以将前面的询问影响到后面的答案,因此考虑倒序做。

可以考虑维护一个栈,不断合并能够合并的点,这样后缀和就是栈顶第一个没被合并的点的后缀加上他们之间的距离

技术图片
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
int p[N];
int find(int x){
    if(p[x]!=x){
        p[x]=find(p[x]);
    }
    return p[x];
}
struct node{
    int l,r;
}s[N];
stack<int> q;
int ql[N],qr[N];
vector<int> ans[N];
int fl[N],fr[N];
ll sum[N];
ll res[N];
int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int i;
    for(i=1;i<=n;i++){
        p[i]=i;
        cin>>s[i].l>>s[i].r;
        s[i].r+=s[i].l-1;
    }
    int m;
    cin>>m;
    for(i=1;i<=m;i++){
        cin>>ql[i]>>qr[i];
        ans[ql[i]].push_back(i);
    }
    for(int i=n;i>=1;i--){
        fl[i]=s[i].l,fr[i]=s[i].r;
        while(q.size()&&fr[i]>=fl[q.top()]){
            int x=q.top();
            q.pop();
            fr[i]=max(fr[i],fr[x]);
            p[find(x)]=i;
        }
        if(!q.empty()){
            sum[i]=sum[q.top()]+fl[q.top()]-fr[i]-1;
        }
        else sum[i]=0;
        q.push(i);
        for(int j=0;j<ans[i].size();j++){
            int id=ans[i][j];
            int a=qr[id];
            res[id]=sum[i]-sum[find(a)];
        }
    }
    for(i=1;i<=m;i++){
        cout<<res[i]<<endl;
    }
}
View Code

 

CF500E New Year Domino(并查集+栈)

标签:bsp   lap   false   图片   覆盖   closed   end   none   std   

原文地址:https://www.cnblogs.com/ctyakwf/p/13807836.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!