P4113 [HEOI2012] 采花 && P1972 [SDOI2009] HH的项链
Solution:
对于区间上的问题,我们都不难想到可以用线段树解决
预处理:
对于一个数
然后我们扫描整个数组:
对于一个询问,我们只在当前枚举的i=r时进行答案统计
对于一个数
我在线段树上对
然后这题就做完了
Code:
P4113 [HEOI2012] 采花
#include<bits/stdc++.h> const int N=2e6+5; using namespace std; int n,cnt,m; //Segment_Tree #define ls x<<1 #define rs x<<1|1 struct Segment_Tree{ struct Tree{ int l,r,val,tag; }t[N<<2]; void pushup(int x) { t[x].val=max(t[ls].val,t[rs].val); } void pushdown(int x) { if(!t[x].tag)return; ////<<"pushdown:"<<t[x].l<<" "<<t[x].r<<"="<<t[x].tag<<"\n"; int tag=t[x].tag; t[ls].tag+=tag,t[rs].tag+=tag; t[ls].val+=tag,t[rs].val+=tag; t[x].tag=0; return; } void build(int x,int l,int r) { t[x].l=l,t[x].r=r; if(l==r) { return; } int mid=l+r>>1; build(ls,l,mid);build(rs,mid+1,r); } void upd(int x,int L,int R,int k) { if(R<t[x].l||t[x].r<L)return; if(R<L)return; if(L<=t[x].l&&t[x].r<=R) { //<<"UPD:"<<t[x].l<<" "<<t[x].r<<"\n"; t[x].val+=k; t[x].tag+=k; return; } int mid=t[x].l+t[x].r>>1; pushdown(x); if(L<=mid)upd(ls,L,R,k); if(mid<R) upd(rs,L,R,k); pushup(x); } int query(int x,int L,int R) { if(L<=t[x].l&&t[x].r<=R) { return t[x].val; } pushdown(x); int mid=t[x].l+t[x].r>>1,res=0; if(L<=mid)res=max(query(ls,L,R),res); if(mid<R) res=max(query(rs,L,R),res); return res; } }T; int a[N],pre[N],last[N],ans[N]; struct task{ int l,r,id; bool operator <(const task t){ return r<t.r; } }q[N]; int tot; int read() { int res=0; char c=getchar(); while(c<'0'||'9'<c)c=getchar(); while('0'<=c&&c<='9')res=(res<<3)+(res<<1)+c-'0',c=getchar(); return res; } void work() { n=read(),tot=read(),m=read(); for(int i=1;i<=n;i++) { a[i]=read(); pre[i]=last[a[i]]; last[a[i]]=i; } for(int i=1;i<=m;i++) { q[i].l=read(); q[i].r=read(); q[i].id=i; } T.build(1,1,n); sort(q+1,q+1+m); int now=1; for(int i=1;i<=n;i++) { T.upd(1,pre[pre[i]]+1,pre[i],1); while(q[now].r==i) { ans[q[now].id]=T.query(1,q[now].l,q[now].r); now++; } } for(int i=1;i<=m;i++) { printf("%d\n",ans[i]); } } int main() { //freopen("flower.in","r",stdin); //freopen("flower.out","w",stdout); work(); }
P1972 [SDOI2009] HH的项链
#include<bits/stdc++.h> const int N=2e6+5; using namespace std; int n,cnt,m; //Segment_Tree #define ls x<<1 #define rs x<<1|1 struct Segment_Tree{ struct Tree{ int l,r,val,tag; }t[N<<2]; void pushup(int x) { t[x].val=max(t[ls].val,t[rs].val); } void pushdown(int x) { if(!t[x].tag)return; ////<<"pushdown:"<<t[x].l<<" "<<t[x].r<<"="<<t[x].tag<<"\n"; int tag=t[x].tag; t[ls].tag+=tag,t[rs].tag+=tag; t[ls].val+=tag,t[rs].val+=tag; t[x].tag=0; return; } void build(int x,int l,int r) { t[x].l=l,t[x].r=r; if(l==r) { return; } int mid=l+r>>1; build(ls,l,mid);build(rs,mid+1,r); } void upd(int x,int L,int R,int k) { if(R<t[x].l||t[x].r<L)return; if(R<L)return; if(L<=t[x].l&&t[x].r<=R) { //<<"UPD:"<<t[x].l<<" "<<t[x].r<<"\n"; t[x].val+=k; t[x].tag+=k; return; } int mid=t[x].l+t[x].r>>1; pushdown(x); if(L<=mid)upd(ls,L,R,k); if(mid<R) upd(rs,L,R,k); pushup(x); } int query(int x,int L,int R) { if(L<=t[x].l&&t[x].r<=R) { return t[x].val; } pushdown(x); int mid=t[x].l+t[x].r>>1,res=0; if(L<=mid)res=max(query(ls,L,R),res); if(mid<R) res=max(query(rs,L,R),res); return res; } }T; int a[N],pre[N],last[N],ans[N]; struct task{ int l,r,id; bool operator <(const task t){ return r<t.r; } }q[N]; int tot; int read() { int res=0; char c=getchar(); while(c<'0'||'9'<c)c=getchar(); while('0'<=c&&c<='9')res=(res<<3)+(res<<1)+c-'0',c=getchar(); return res; } void work() { n=read(); for(int i=1;i<=n;i++) { a[i]=read(); pre[i]=last[a[i]]; last[a[i]]=i; } m=read(); for(int i=1;i<=m;i++) { q[i].l=read(); q[i].r=read(); q[i].id=i; } T.build(1,1,n); sort(q+1,q+1+m); int now=1; for(int i=1;i<=n;i++) { T.upd(1,pre[i]+1,i,1); while(q[now].r==i) { ans[q[now].id]=T.query(1,q[now].l,q[now].r); now++; } } for(int i=1;i<=m;i++) { printf("%d\n",ans[i]); } } int main() { //freopen("flower.in","r",stdin); //freopen("flower.out","w",stdout); work(); }