Time Limit: 20000MS | Memory Limit: 65536K | |
Total Submissions: 20110 | Accepted: 5251 | |
Case Time Limit: 2000MS |
Description
Input
Output
Sample Input
7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3
Sample Output
5 6 3
此题是我做线段树专辑遇到的一题比较棘手的。。。
还是参考了其他人的思路才过了,之前一直TLE - -!
#include <iostream> using namespace std; #define N 100005 struct LineTree { int l,r; int depth; LineTree *lchild,*rchild; }; int pos,x,y,key; LineTree mem[3*N]; int val[N]; int res[20][N]; LineTree *NewTree() { LineTree *s=&mem[pos++]; return s; } LineTree *CreateTree(int a,int b,int dep) { LineTree *s=NewTree(); s->l=a; s->r=b; s->depth=dep; int mid; if(a!=b) { mid=(a+b)/2; s->lchild=CreateTree(a,mid,dep+1); s->rchild=CreateTree(mid+1,b,dep+1); int i=s->l,j=mid+1,l=s->l; while ( i <= mid && j <= b ) { if ( res [dep + 1] [i] < res [dep + 1] [j] ) res [dep] [l ++] = res [dep + 1] [i ++]; else res [dep] [l ++] = res [dep + 1] [j ++]; } while ( i <= mid ) res [dep] [l ++] = res [dep + 1] [i ++]; while ( j <= s->r ) res [dep] [l ++] = res [dep + 1] [j ++]; } else { res[dep][a]=val[a]; } return s; } int search(LineTree *s) { if ( x <= s->l && s->r <= y ) { if ( res [s->depth] [s->l] >= key ) return 0; if ( res [s->depth] [s->r] < key ) return s->r - s->l + 1; if ( res [s->depth] [s->r] == key ) return s->r - s->l; int low = s->l , high = s->r , mid; while ( low + 1 < high ) { mid = ( low + high )/2; if ( res [s->depth] [mid] < key ) low = mid; else high = mid; } return low - s->l + 1; } int ret = 0; if ( x <= s->lchild->r ) ret += search(s->lchild); if ( s->rchild->l <= y ) ret += search(s->rchild); return ret; } int main() { int n,m,i,c,low,high,mid; while(scanf("%d%d",&n,&m)!=EOF) { for(i=0;i<n;i++) scanf("%d",&val[i]); pos=1; LineTree *s; s=CreateTree(0,n-1,0); while(m--) { scanf("%d%d%d",&x,&y,&c); x --; y --; low = 0; high = n; while ( low + 1 < high ) { mid = ( low + high ) / 2; key = res [0] [mid]; if ( search(s) >= c ) high = mid; else low = mid; } printf("%d/n",res[0][low]); } } return 0; }