标签:UI printf int tor iterator oid images 技术分享 struct
题意:给一些多米诺骨牌,可以花费$1$的代价延长某个骨牌的生命长度,询问推倒一段区间的骨牌要花多少代价

这道题我是不是鸽了一个月233333
首先离散化,然后建线段树存哪些区间没有被覆盖
前面的骨牌可能太长以至于影响后面骨牌的统计答案,所以我们要离线询问,从后往前做
添加一个骨牌$\Rightarrow$区间置$0$
询问$\Rightarrow$区间求和
单调栈什么的人家不懂啦
#include<stdio.h>
#include<vector>
#include<map>
#include<string.h>
using namespace std;
struct ask{
int r,id;
ask(int a=0,int b=0){
r=a;
id=b;
}
};
vector<ask>lr[200010];
vector<ask>::iterator vit;
map<int,int>pos;
map<int,int>::iterator it;
int p[200010],l[200010],ans[200010],laz[1600010],sum[1600010];
void pushup(int x){
sum[x]=sum[x<<1]+sum[x<<1|1];
}
void build(int l,int r,int x){
if(l==r){
sum[x]=laz[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,x<<1);
build(mid+1,r,x<<1|1);
pushup(x);
}
void pushdown(int x){
if(laz[x]){
laz[x<<1]=laz[x<<1|1]=1;
sum[x<<1]=sum[x<<1|1]=0;
laz[x]=0;
}
}
void modify(int L,int R,int l,int r,int x){
if(L<=l&&r<=R){
laz[x]=1;
sum[x]=0;
return;
}
pushdown(x);
int mid=(l+r)>>1;
if(L<=mid)modify(L,R,l,mid,x<<1);
if(mid<R)modify(L,R,mid+1,r,x<<1|1);
pushup(x);
}
int query(int L,int R,int l,int r,int x){
if(L<=l&&r<=R)return sum[x];
pushdown(x);
int mid=(l+r)>>1,ans=0;
if(L<=mid)ans+=query(L,R,l,mid,x<<1);
if(mid<R)ans+=query(L,R,mid+1,r,x<<1|1);
return ans;
}
int main(){
int n,q,i,a,b,M;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d",p+i,l+i);
pos[p[i]]=1;
pos[p[i]+l[i]]=1;
}
for(it=pos.begin(),M=1;it!=pos.end();it++,M++){
(it->second)=M;
laz[M-1]=(it->first)-laz[M-1];
laz[M]=(it->first);
}
build(1,M-1,1);
memset(laz,0,sizeof(laz));
scanf("%d",&q);
for(i=1;i<=q;i++){
scanf("%d%d",&a,&b);
lr[a].push_back(ask(b,i));
}
for(i=n;i>0;i--){
modify(pos[p[i]],pos[p[i]+l[i]]-1,1,M-1,1);
for(vit=lr[i].begin();vit!=lr[i].end();vit++){
if((*vit).r==i)
ans[(*vit).id]=0;
else
ans[(*vit).id]=query(pos[p[i]],pos[p[(*vit).r]]-1,1,M-1,1);
}
}
for(i=1;i<=q;i++)printf("%d\n",ans[i]);
}
标签:UI printf int tor iterator oid images 技术分享 struct
原文地址:http://www.cnblogs.com/jefflyy/p/7791780.html