给出n个数,m个询问,每次查询在[L,R]中≤x的数有多少个.
在线做的话是主席树模板了
离线做将查询按位置先后排序
逐个向树状数组中插入数,并回答询问(类似查询逆序对)
最后再按时间排回来
都需要离散化.
因为是小于等于,二分的时候要upper_bound.坑死了
多组数据初始化坑爹啊。。
主席树
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define LL long long #define clr(x,i) memset(x,i,sizeof(x)) using namespace std; const int N=100005; struct Node{ int l,r,sum; }t[N*36]; vector<int> v; int n,m,a[N],rt[N],cnt,sz; int getid(int x) { return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } void update(int l,int r,int &x,int y,int pos) { t[++cnt]=t[y];t[cnt].sum++;x=cnt; if(l==r)return; int mid=(l+r)>>1; if(pos<=mid) update(l,mid,t[x].l,t[y].l,pos); else update(mid+1,r,t[x].r,t[y].r,pos); } int query(int l,int r,int x,int y,int K) { if(l==r)return t[y].sum-t[x].sum; int mid=(l+r)>>1; int sum=t[t[y].l].sum-t[t[x].l].sum; if(mid>=K) return query(l,mid,t[x].l,t[y].l,K); else return query(mid+1,r,t[x].r,t[y].r,K)+sum; } int res[N],tot; void solve() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]),v.push_back(a[i]); sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); sz=v.end()-v.begin(); for(int i=1;i<=n;i++) update(1,sz,rt[i],rt[i-1],getid(a[i])); int p,q,h,tmp;tot=0; while(m--) { scanf("%d%d%d",&p,&q,&h); tmp=upper_bound(v.begin(),v.end(),h)-v.begin(); //printf("%d ",tmp); int ret1=query(1,sz,rt[p],rt[q+1],tmp); //res[++tot]=ret1; if(tmp)res[++tot]=ret1; else res[++tot]=0; } for(int i=1;i<=tot;i++)printf("%d\n",res[i]); } void init() { for(int i=0;i<=cnt;i++) rt[i]=0,t[i].l=t[i].r=t[i].sum=0; cnt=0; v.erase(v.begin(),v.end()); } int main() { //freopen("4417.in","r",stdin); //freopen("4417.ans","w",stdout); int cas;scanf("%d",&cas); for(int t=1;t<=cas;t++){ init();printf("Case %d:\n",t);solve(); } return 0; }
离线树状数组
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define LL long long #define clr(x,i) memset(x,i,sizeof(x)) #define lowbit(x) (x&(-x)) using namespace std; const int N=100005; struct Q{ int pos,x,id,ans; }q[N*4]; int n,m,a[N],c[N],tot; bool cmp1(const Q &a,const Q &b) { return a.pos<b.pos; } bool cmp2(const Q &a,const Q &b) { return a.id==b.id ? a.pos<b.pos : a.id<b.id; } vector<int> v; inline int getid(int x) { return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } inline void Add(int x) { while(x<=n){ c[x]++;x+=lowbit(x); } } inline int ask(int x) { int ret=0; while(x){ ret+=c[x];x-=lowbit(x); } return ret; } void solve() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]),v.push_back(a[i]); sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); int x,y,K; for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&K); x++;y++; q[++tot].pos=x-1;q[tot].x=K;q[tot].id=i; q[++tot].pos=y;q[tot].x=K;q[tot].id=i; } sort(q+1,q+tot+1,cmp1); int now=0,ans,val; for(int i=1;i<=tot;i++) { while(q[i].pos>now) Add(getid(a[++now])); val=upper_bound(v.begin(),v.end(),q[i].x)-v.begin(); q[i].ans=ask(val); } sort(q+1,q+tot+1,cmp2); for(int i=1;i<=m;i++) { ans=q[i*2].ans-q[i*2-1].ans; printf("%d\n",ans); } } void init() { v.erase(v.begin(),v.end()); tot=0; for(int i=0;i<=n;i++)c[i]=0; } int main() { //freopen("4417.in","r",stdin); //freopen("4417.out","w",stdout); int cas;scanf("%d",&cas); for(int t=1;t<=cas;t++){ init();printf("Case %d:\n",t);solve(); } return 0; }