HDU 4417 Super Mario(主席樹)
阿新 • • 發佈:2018-04-19
there mon ref seve pin ans ins Go follow
Input
The first line follows an integer T, the number of test data.
For each test data:
The first line contains two integers n, m (1 <= n <=10^5, 1 <= m <= 10^5), n is the length of the road, m is the number of queries.
Next line contains n integers, the height of each brick, the range is [0, 1000000000].
Next m lines, each line contains three integers L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000.)
Output
For
each case, output "Case X: " (X is the case number starting from 1)
followed by m lines, each line contains an integer. The ith integer is
the number of bricks Mario can hit for the ith query.
Sample Output
Case 1:
4
0
0
3
1
2
0
1
5
1
Super Mario
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8365 Accepted Submission(s): 3540
For each test data:
The first line contains two integers n, m (1 <= n <=10^5, 1 <= m <= 10^5), n is the length of the road, m is the number of queries.
Next line contains n integers, the height of each brick, the range is [0, 1000000000].
Next m lines, each line contains three integers L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000.)
Sample Input 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
Source 2012 ACM/ICPC Asia Regional Hangzhou Online
Recommend liuyiding | We have carefully selected several similar problems for you: 6275 6274 6273 6272 6271 題意是求 區間[L,R]的小於等於h的數的個數 主席樹的模板題 代碼如下:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<queue> #include<map> #include<stack> #include<vector> using namespace std; const int MAXN=1e5+10; int a[MAXN],root[MAXN]; int t,n,m,l,r,x; vector<int>v; int get_id(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;} //因為每個數的範圍很大,需要進行離散化處理 struct node { int l; int r; int h; }qes[MAXN]; struct Node { int l; int r; int sum; }T[MAXN*40]; int cnt; int ans; 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); } void query(int l,int r,int x,int y,int k) { int mid=(l+r)>>1; if(mid==k)// 如果小於等於k的數剛好全部在左邊區域,加上它的權值,直接結束 { ans+=T[T[y].l].sum-T[T[x].l].sum; return; } else if(k<mid) //左邊存在部分小於等於k的數,查詢左邊區域 query(l,mid,T[x].l,T[y].l,k); else//右邊存在部分小於k的數,則加上左邊的權值,並查詢右邊區域。 { ans+=T[T[y].l].sum-T[T[x].l].sum; query(mid+1,r,T[x].r,T[y].r,k); } } int main() { scanf("%d",&t); int Case=0; while(t--) { Case++; cnt=0; v.clear(); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); v.push_back(a[i]); } for(int i=1;i<=m;i++) { scanf("%d%d%d",&qes[i].l,&qes[i].r,&qes[i].h); v.push_back(qes[i].h); } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); int sz=v.size(); for(int i=1;i<=n;i++) Update(1,sz,root[i],root[i-1],get_id(a[i])); printf("Case %d:\n",Case); for(int i=1;i<=m;i++) { ans=0; query(1,sz,root[qes[i].l],root[qes[i].r+1],get_id(qes[i].h)); printf("%d\n",ans); } } return 0; }
HDU 4417 Super Mario(主席樹)