題意:
同上
題解:
抓著這題作死的搞~~是因為今天練習賽的一道題.SPOJ
KQUERY.直到我用最後一種樹狀數組通過了HDOJ這題後..交SPOJ的才沒逾時..看排名...時間能排到11名了..有些叼...看下時間效率..自下而上: 劃分樹、線段樹、樹狀數組、最佳化後的樹狀數組...
劃分樹的效率最低...看來劃分樹的應用範圍還是是很有局限性...只在求kth number的時候給力..逆過來求就已經力不從心了...
線段樹及樹狀數組處理本題..需要把詢問都存下來...按照詢問數從小到大按排個序..並且把每個數以及其序號存下來..按數字從小到大排個序...首先這一列數都是空的(全0)..然後邊放數邊統計結果...
Program: 線段樹171MS
#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#include<algorithm>#define ll long long#define eps 1e-5#define oo 1000000007#define pi acos(-1.0)#define MAXN 100005using namespace std;struct node{ int x,w; }p[MAXN];struct question{ int l,r,x,id; }q[200005];int sum[MAXN<<2],ans[200005];void update(int p,int x,int l,int r,int now){ if (l==r) { sum[now]=x; return; } int mid=l+r>>1; if (p<=mid) update(p,x,l,mid,now<<1); if (p>mid) update(p,x,mid+1,r,now<<1|1); sum[now]=sum[now<<1]+sum[now<<1|1]; return; }int query(int L,int R,int l,int r,int now){ if (L<=l && R>=r) return sum[now]; int mid=l+r>>1,ans=0; if (L<=mid) ans+=query(L,R,l,mid,now<<1); if (R>mid) ans+=query(L,R,mid+1,r,now<<1|1); return ans;}bool cmp1(node a,node b) { return a.x<b.x; }bool cmp2(question a,question b) { return a.x<b.x; } int main(){ int n,m,i,x,t,h,T,cases; scanf("%d",&T); for (cases=1;cases<=T;cases++) { printf("Case %d:\n",cases); scanf("%d%d",&n,&m); for (i=1;i<=n;i++) scanf("%d",&p[i].x),p[i].w=i; sort(p+1,p+1+n,cmp1); p[n+1].x=oo; for (i=1;i<=m;i++) { scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].x); q[i].l++,q[i].r++; q[i].id=i; } sort(q+1,q+1+m,cmp2); memset(sum,0,sizeof(sum)); h=x=1; while (x<=n && h<=m) { t=p[x].x; while (p[x].x==t) update(p[x].w,1,1,n,1),x++; while (h<=m && q[h].x<t) ans[q[h].id]=0,h++; while (h<=m && q[h].x<p[x].x) ans[q[h].id]=query(q[h].l,q[h].r,1,n,1),h++; } for (i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0;}
Program: 樹狀數組 125MS
#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#include<algorithm>#define ll long long#define eps 1e-5#define oo 1000000007#define pi acos(-1.0)#define MAXN 100005using namespace std;struct node{ int x,w; }p[MAXN];struct question{ int l,r,x,id; }q[200005];int sum[MAXN],ans[200005],n; void insert(int x,int k){ while (k<=n) { sum[k]+=x; k+=k&(-k); } return;}int query(int k){ int ans=0; while (k) { ans+=sum[k]; k-=k&(-k); } return ans;}bool cmp1(node a,node b) { return a.x<b.x; }bool cmp2(question a,question b) { return a.x<b.x; } int main(){ int m,i,x,t,h,T,cases; scanf("%d",&T); for (cases=1;cases<=T;cases++) { printf("Case %d:\n",cases); scanf("%d%d",&n,&m); for (i=1;i<=n;i++) scanf("%d",&p[i].x),p[i].w=i; sort(p+1,p+1+n,cmp1); p[n+1].x=oo; for (i=1;i<=m;i++) { scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].x); q[i].l++,q[i].r++; q[i].id=i; } sort(q+1,q+1+m,cmp2); memset(sum,0,sizeof(sum)); h=x=1; while (x<=n && h<=m) { t=p[x].x; while (p[x].x==t) insert(1,p[x].w),x++; while (h<=m && q[h].x<t) ans[q[h].id]=0,h++; while (h<=m && q[h].x<p[x].x) ans[q[h].id]=query(q[h].r)-query(q[h].l-1),h++; } for (i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0;}
Program: 樹狀數組 78MS
#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#include<algorithm>#define ll long long#define eps 1e-5#define oo 1000000007#define pi acos(-1.0)#define MAXN 100005#define MAXM 200005using namespace std;struct node{ int x,w; }p[MAXN]; int sum[MAXN],ans[200005],n,ql[MAXM],qr[MAXM],qx[MAXM],qid[MAXM]; void insert(int x,int k){ while (k<=n) { sum[k]+=x; k+=k&(-k); } return;}int query(int k){ int ans=0; while (k) { ans+=sum[k]; k-=k&(-k); } return ans;}int input(){ char c; do { c=getchar(); }while (c<'0' || c>'9'); int d=0; while (c>='0' && c<='9') { d=d*10+c-'0'; c=getchar(); } return d;}bool cmp1(node a,node b) { return a.x<b.x; }bool cmp2(int a,int b) { return qx[a]<qx[b]; } int main(){ int m,i,x,t,h,T,cases; scanf("%d",&T); for (cases=1;cases<=T;cases++) { printf("Case %d:\n",cases); scanf("%d%d",&n,&m); for (i=1;i<=n;i++) p[i].x=input(),p[i].w=i; sort(p+1,p+1+n,cmp1); p[n+1].x=oo; for (i=1;i<=m;i++) { ql[i]=input()+1,qr[i]=input()+1,qx[i]=input(); qid[i]=i; } sort(qid+1,qid+1+m,cmp2); memset(sum,0,sizeof(sum)); h=x=1; while (x<=n && h<=m) { t=p[x].x; while (p[x].x==t) insert(1,p[x].w),x++; while (h<=m && qx[qid[h]]<t) ans[qid[h]]=0,h++; while (h<=m && qx[qid[h]]<p[x].x) ans[qid[h]]=query(qr[qid[h]])-query(ql[qid[h]]-1),h++; } for (i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0;}