1 10 10 0 5 2 7 5 4 3 8 7 7 2 8 6 3 5 0 1 3 1 1 9 4 0 1 0 3 5 5 5 5 1 4 6 3 1 5 7 5 7 3
Case 1: 4 0 0 3 1 2 0 1 5 1
普通的線段樹果斷T成狗,故轉向離線。
將磚塊高度val和瑪麗能跳的高度H都存起來,更新p[k].val<=q[i].h的,區間求和的時候就能保證當前更新的都是小於瑪麗能跳的的高度。。。
#include#include #include #include #include typedef long long LL; using namespace std; const int maxn=1e5+10; struct tree{ int l,r; int cnt; }t[maxn<<2]; struct node1{ int val; int pos; bool operator<(const node1 l1)const{ return val >1; build(rs<<1,l,mid); build(rs<<1|1,mid+1,r); } void update(int rs,int pos) { t[rs].cnt++; if(t[rs].l==t[rs].r) return ; int mid=(t[rs].l+t[rs].r)>>1; if(pos<=mid) update(rs<<1,pos); else update(rs<<1|1,pos); } int query(int l,int r,int rs) { if(t[rs].l==l&&t[rs].r==r) return t[rs].cnt; int mid=(t[rs].l+t[rs].r)>>1; if(r<=mid) return query(l,r,rs<<1); else if(l>mid) return query(l,r,rs<<1|1); else return query(l,mid,rs<<1)+query(mid+1,r,rs<<1|1); } int main() { int t,n,m; int cas=1; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); build(1,1,n); for(int i=1;i<=n;i++) { scanf("%d",&p[i].val); p[i].pos=i; } for(int i=1;i<=m;i++) { scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h); q[i].id=i; } sort(p+1,p+1+n); sort(q+1,q+1+m); int k=1; for(int i=1;i<=m;i++) { while(k<=n&&p[k].val<=q[i].h) { update(1,p[k].pos); k++; } ans[q[i].id]=query(q[i].l+1,q[i].r+1,1); } printf("Case %d:\n",cas++); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0; }
另外樹狀數組也可以做。類似的單點更新和區間求和問題都可以用樹狀數組來寫。
類似離線線段樹的思想將節點和詢問保存排序後依次更新,就能保證結果的正確性。
#include#include #include #include #include typedef long long LL; using namespace std; const int maxn=1e5+10; int cnt[maxn]; struct node1{ int val; int pos; bool operator<(const node1 l1)const{ return val 0) { s+=cnt[x]; x-=lowbit(x); } return s; } int main() { int t,n,m; int cas=1; scanf("%d",&t); while(t--) { memset(cnt,0,sizeof(cnt)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&p[i].val); p[i].pos=i; } for(int i=1;i<=m;i++) { scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h); q[i].id=i; } sort(p+1,p+1+n); sort(q+1,q+1+m); int k=1; for(int i=1;i<=m;i++) { while(k<=n&&p[k].val<=q[i].h) { update(p[k].pos); k++; } ans[q[i].id]=query(q[i].r+1)-query(q[i].l); } printf("Case %d:\n",cas++); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0; }