首页 > 代码库 > Super Mario(线段树离线区间k值)
Super Mario(线段树离线区间k值)
以前见过这题,没做出来,知道是离线处理,这次仔细想了下,
首先把出现的高度都map离散化一下,以离散化出来的数目g建树,把每个位置都开俩个vector,一个存以这个位置为L的询问,一个存以这个位置为R的询问。
然后从1-g 进行更新,假如当前i是以第j个区间的开始位置,那么这时就可以询问一下<=p[j].h的个数s,显然这时第J个区间多加的,需要减掉,p[j].sum-=s;
然后更新第i个数,update(a[i],1,g,1);再找到某第k区间是以i结尾的,那么依旧询问一下,得出s,p[k].sum+=s;这样就是最终结果。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 #include<map> 11 using namespace std; 12 #define N 200010 13 #define LL long long 14 #define INF 0xfffffff 15 const double eps = 1e-8; 16 const double pi = acos(-1.0); 17 const double inf = ~0u>>2; 18 int s[N<<2],a[N],b[N]; 19 map<int,int>f; 20 vector<int>st[N]; 21 vector<int>ed[N]; 22 struct node 23 { 24 int l,r,h; 25 int sum; 26 }p[N]; 27 bool cmp(node a,node b) 28 { 29 if(a.l==b.l) 30 return a.r<b.r; 31 return a.l==b.l; 32 } 33 void up(int w) 34 { 35 s[w] = s[w<<1]+s[w<<1|1]; 36 } 37 void build(int l,int r,int w) 38 { 39 if(l==r) 40 { 41 s[w] = 0; 42 return ; 43 } 44 int m = (l+r)>>1; 45 build(l,m,w<<1); 46 build(m+1,r,w<<1|1); 47 up(w); 48 } 49 void update(int p,int l,int r,int w) 50 { 51 if(l==r) 52 { 53 s[w] += 1; 54 return ; 55 } 56 int m = (l+r)>>1; 57 if(p<=m) 58 update(p,l,m,w<<1); 59 else 60 update(p,m+1,r,w<<1|1); 61 up(w); 62 } 63 int query(int a,int b,int l,int r,int w) 64 { 65 if(a<=l&&b>=r) 66 { 67 return s[w]; 68 } 69 int m = (l+r)>>1; 70 int res =0; 71 if(a<=m) 72 res+=query(a,b,l,m,w<<1); 73 if(b>m) 74 res+=query(a,b,m+1,r,w<<1|1); 75 return res; 76 } 77 int main() 78 { 79 int t,n,q,i,j; 80 int kk = 0; 81 scanf("%d",&t); 82 while(t--) 83 { 84 int g = 0; 85 scanf("%d%d",&n,&q); 86 f.clear(); 87 for(i = 1; i <= n; i++) 88 { 89 scanf("%d",&a[i]); 90 b[i] = a[i]; 91 st[i].clear(); 92 ed[i].clear(); 93 } 94 for(i =1;i <= q ;i++) 95 { 96 scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].h); 97 p[i].l++,p[i].r++; 98 p[i].sum = 0; 99 st[p[i].l].push_back(i); 100 ed[p[i].r].push_back(i); 101 a[n+i] = p[i].h; 102 } 103 sort(a,a+n+q+1); 104 f[a[1]] = ++g; 105 for(i = 2; i <= n+q ; i++) 106 { 107 if(a[i]!=a[i-1]) 108 f[a[i]] = ++g; 109 } 110 build(1,g,1); 111 for(i = 1; i <= n ;i++) 112 { 113 if(st[i].size()!=0) 114 { 115 for(j = 0 ;j < st[i].size() ; j++) 116 { 117 int v = st[i][j]; 118 int pre = query(1,f[p[v].h],1,g,1); 119 p[v].sum -= pre; 120 } 121 } 122 update(f[b[i]],1,g,1); 123 if(ed[i].size()) 124 { 125 for(j = 0; j < ed[i].size() ;j++) 126 { 127 int v= ed[i][j]; 128 int bef = query(1,f[p[v].h],1,g,1); 129 p[v].sum+=bef; 130 } 131 } 132 } 133 printf("Case %d:\n",++kk); 134 for(i = 1; i <= q ; i++) 135 { 136 printf("%d\n",p[i].sum); 137 } 138 } 139 return 0; 140 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。