題意:查詢區間中位數
思路:模板題,相當於區間第k大的數,主席樹可以水過,但劃分樹是正解。但還沒搞明白劃分樹,先上模板
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include主席樹先上kb模板7 #include 8 #include 9 #include
10#define repu(i,a,b) for(int i=a;i11
using
namespace
std;
12#define n 1000010
13#define ll long long
14#define _cle(m, a) memset(m, a, sizeof(m))
15const
int maxn = 100010;16
const
int m = maxn * 30;17
intn,q,m,tot;
18int
a[maxn], t[maxn];
19int
t[maxn], lson[m], rson[m], c[m];
20void
init_hash()
2127
int build(int l, int
r)28
37return
root;38}
39int hash(int
x)40
43int update(int root, int pos, int
val)
4459
else
6067 c[newroot] = c[root] +val;68}
69return
tmp;70}
71int query(int left_root, int right_root, int
k)72
83else
8490}91
return
l;92}93
intmain()
94110 printf("
case %d:\n
",kase++);
111 scanf("
%d",&q);
112while(q--)
113119
}120
return0;
121 }
1劃分樹//劃分樹
2 #include3 #include4 #include5
using
namespace
std;
6const
int maxn=100010;7
int tree[20][maxn];//
表示每層每個位置的值
8int sorted[maxn];//
已經排序好的數
9int toleft[20][maxn];//
toleft[p][i]表示第i層從1到i有數分入左邊
10void build(int l,int r,int
dep)
24else tree[dep+1][rpos++]=tree[dep][i];
25 toleft[dep][i]=toleft[dep][l-1]+lpos-l;26}
27 build(l,mid,dep+1
);28 build(mid+1,r,dep+1
);29}30
//查詢區間第k大的數,[l,r]是大區間,[l,r]是要查詢的小區間
31int query(int l,int r,int l,int r,int dep,int
k)39
else43}
44int
main()
52 sort(sorted+1,sorted+n+1
);53 build(1,n,0
);54 scanf("
%d",&m);
55 printf("
case %d:\n
",++t);
56int
s,t,k;
57while(m--)62}
63return0;
64 }
劃分樹模板 模板題 hdu4251
劃分樹解決的是快速求區間中第k大值的問題,演算法的主要思想是基於線段樹和快排的劃分方法,可以實現在logn時間內求出任意區間的第k大值。下面這份 是基於hud4251的乙份模板。如下 include include include include using namespace std const ...
HDU5790 Prefix 字典樹 主席樹
分析 這個題和spoj的d query是乙個題,那個是求一段區間裡有多少個不同的數字,這裡是統計有多少個不同的字首 用字典樹進行判重,和查詢不同的數字一樣 對於每個不同的字首,只保留它最後一次出現的序號 include include include include using namespace ...
HDU4417(主席樹計數)
解題思路 如果說用排序,那麼複雜度就是o mnlogn 會超時。用主席樹的空間複雜度是o nlogn 時間複雜度是o max nlogn,mlogn 這道題稍微修改一下query函式即可。include include include include define n 100009 using na...