标签: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