Super Mario(线段树离线区间k值)
2014-05-29 16:15
363 查看
以前见过这题,没做出来,知道是离线处理,这次仔细想了下,
首先把出现的高度都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;这样就是最终结果。
View Code
首先把出现的高度都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;这样就是最终结果。
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<stdlib.h> #include<vector> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define N 200010 #define LL long long #define INF 0xfffffff const double eps = 1e-8; const double pi = acos(-1.0); const double inf = ~0u>>2; int s[N<<2],a ,b ; map<int,int>f; vector<int>st ; vector<int>ed ; struct node { int l,r,h; int sum; }p ; bool cmp(node a,node b) { if(a.l==b.l) return a.r<b.r; return a.l==b.l; } void up(int w) { s[w] = s[w<<1]+s[w<<1|1]; } void build(int l,int r,int w) { if(l==r) { s[w] = 0; return ; } int m = (l+r)>>1; build(l,m,w<<1); build(m+1,r,w<<1|1); up(w); } void update(int p,int l,int r,int w) { if(l==r) { s[w] += 1; return ; } int m = (l+r)>>1; if(p<=m) update(p,l,m,w<<1); else update(p,m+1,r,w<<1|1); up(w); } int query(int a,int b,int l,int r,int w) { if(a<=l&&b>=r) { return s[w]; } int m = (l+r)>>1; int res =0; if(a<=m) res+=query(a,b,l,m,w<<1); if(b>m) res+=query(a,b,m+1,r,w<<1|1); return res; } int main() { int t,n,q,i,j; int kk = 0; scanf("%d",&t); while(t--) { int g = 0; scanf("%d%d",&n,&q); f.clear(); for(i = 1; i <= n; i++) { scanf("%d",&a[i]); b[i] = a[i]; st[i].clear(); ed[i].clear(); } for(i =1;i <= q ;i++) { scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].h); p[i].l++,p[i].r++; p[i].sum = 0; st[p[i].l].push_back(i); ed[p[i].r].push_back(i); a[n+i] = p[i].h; } sort(a,a+n+q+1); f[a[1]] = ++g; for(i = 2; i <= n+q ; i++) { if(a[i]!=a[i-1]) f[a[i]] = ++g; } build(1,g,1); for(i = 1; i <= n ;i++) { if(st[i].size()!=0) { for(j = 0 ;j < st[i].size() ; j++) { int v = st[i][j]; int pre = query(1,f[p[v].h],1,g,1); p[v].sum -= pre; } } update(f[b[i]],1,g,1); if(ed[i].size()) { for(j = 0; j < ed[i].size() ;j++) { int v= ed[i][j]; int bef = query(1,f[p[v].h],1,g,1); p[v].sum+=bef; } } } printf("Case %d:\n",++kk); for(i = 1; i <= q ; i++) { printf("%d\n",p[i].sum); } } return 0; }
View Code
相关文章推荐
- hdu4417:线段树单点更新区间求和,离线 Super Mario
- [hdu3333 Turing Tree] 线段树离线 处理区间不同数
- hdu4288 Coder 离线线段树 单点更新 区间求和 离散化?
- HDU 4417 - Super Mario (求区间小于h的数 划分树 二分 线段树 树状数组)
- hdu4417- Super Mario(离线,线段树)
- hdu5493(线段树,离线操作,点修改,区间查询)
- HDU 4417 Super Mario(线段树||树状数组+离线操作 之线段树篇)
- hdu 3333 Turing Tree 线段树 离线查询(区间内不同的数之和)
- HDU 4417 Super Mario(12年杭州 离线线段树||在线划分树)
- hdu 3333 Turing Tree(线段树求区间内不同值之和+离线处理)
- [CF#365 (Div. 2) Mishka and Interesting sum] 线段树离线处理区间不同数
- HDU 4417 Super Mario(2012杭州网络赛 H 离线线段树)
- HDU 4417 Super Mario(离线线段树)
- HDU 4417 Super Mario(离线线段树)
- HDU 5700 区间交 离线线段树
- HDU 3874 Necklace (线段树单点更新+区间查询+离线操作)
- HDU 4417 Super Mario(2012杭州网络赛 H 离线线段树)
- Codeforces 482B 线段树与离线区间加和问题
- hdu2795Billboard(线段树单点更新 区间K值)
- HDU 4417 Super Mario(线段树||树状数组+离线操作 之树状数组篇)