划分树几道题目
来源:互联网 发布:手机淘宝安卓版 编辑:程序博客网 时间:2024/05/21 08:55
主要参考kuangbin博客
个人感觉划分树是基于快速排序的分治的思想,是把快速排序每个过程记录下来而已(借助快速排序也是可以快速求整个区间第k值的)
对于每个区间,找中间值比较分成两个子区间,再递归处理
划分树Hdu4251(区间第k值)
typedef long long LL;typedef unsigned long long ULL;typedef vector <int> VI;const int INF = 1000000000;#define lson l, m, dep + 1#define rson m + 1, r, dep + 1const int maxn = 100010;const int deep = 30; int t[deep][maxn];int st[maxn];int toleft[deep][maxn]; void build(int l, int r, int dep){ int i; if (l == r) return; int m = (r + l) >> 1; int same = m - l + 1;//表示等于中间值而且被分入左边的个数 for (i = l; i <= r; i++) if (t[dep][i] < st[m]) same--; int lpos = l; int rpos = m + 1; for (i = l; i <= r; i++) { if (t[dep][i] < st[m])//比中间的数小,分入左边 t[dep + 1][lpos++] = t[dep][i]; else if (t[dep][i] == st[m] && same > 0) { t[dep + 1][lpos++] = t[dep][i]; same--; } else// if (t[dep][i] > st[m]) //比中间值大分入右边 t[dep + 1][rpos++] = t[dep][i]; toleft[dep][i] = toleft[dep][l - 1] + lpos - l;//从1到i放左边的个数 } build(lson); build(rson);} //查询区间第k大的数,[l,r]是大区间,[L,R]是要查询的小区间int query(int L, int R, int k,int l, int r,int dep){ if (l == r) return t[dep][l];///!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 int m = (l + r) >> 1; int cnt = toleft[dep][R] - toleft[dep][L - 1];//[L,R]中位于左边的个数 if (cnt >= k) { //l+要查询的区间前被放在左边的个数 int newl = l + toleft[dep][L - 1] - toleft[dep][l - 1]; //左端点加上查询区间会被放在左边的个数 int newr = newl + cnt - 1; return query(newl, newr, k, lson);///!!!!!newl, newr } else { int newr = R + toleft[dep][r] - toleft[dep][R]; int newl = newr - (R - L - cnt); return query(newl, newr, k - cnt, rson);///!!!!!! }} int main(){ int n, m; int a, b; int p = 1; while (cin >> n) { CLR(t, 0);/// FE(i, 1, n)/// { RI(t[0][i]); st[i] = t[0][i]; } sort(st + 1, st + n + 1);/// build(1, n, 0);/// printf("Case %d:\n",p++); cin >> m; REP(i, m) { RII(a, b); printf("%d\n",query(a, b, (b - a) / 2 + 1, 1, n, 0)); } }}
划分树hdu 3473 (Minimum Sum )增加了一个lsum【】函数
typedef long long LL;typedef unsigned long long ULL;typedef vector <int> VI;const int INF = 1000000000;const int maxn = 100010;const int deep = 20; #define lson l, m, dep + 1#define rson m + 1, r, dep + 1 int t[deep][maxn];int toleft[deep][maxn];int st[maxn];LL lsum[deep][maxn];//LL sum[maxn];LL ans; void build(int l, int r, int dep){ if (l == r) { lsum[dep][l] = t[dep][l]; return ; } int m = (l + r) >> 1; int same = m - l + 1; FE(i, l, r) { if (t[dep][i] < st[m]) same--; lsum[dep][i] = t[dep][i]; if (i != l) lsum[dep][i] += lsum[dep][i - 1]; } int lpos = l; int rpos = m + 1; FE(i, l, r) { if (t[dep][i] < st[m]) t[dep + 1][lpos++] = t[dep][i]; else if (t[dep][i] == st[m] && same > 0) { t[dep + 1][lpos++] = t[dep][i]; same--; } else t[dep + 1][rpos++] = t[dep][i]; toleft[dep][i] = toleft[dep][l - 1] + lpos - l;/// } build(lson); build(rson);} int query(int L,int R, int k, int l, int r,int dep){ if (L == R ) return t[dep][L]; int cnt = toleft[dep][R] - toleft[dep][L - 1]; int m = (l + r) >> 1; int ln1 = toleft[dep][L - 1] - toleft[dep][l - 1]; int rn1 = L - l - ln1; int ln2 = cnt; int rn2 = R - L + 1 - cnt; if (cnt >= k) { if (rn2 > 0) { if (rn1 > 0) ans += lsum[dep + 1][m + rn1 +rn2] - lsum[dep + 1][m + rn1];///@@@@///dep + 1 else ans += lsum[dep + 1][m + rn2]; } int newl = l + ln1; int newr = newl + cnt - 1; return query(newl, newr, k, lson); } else { if (ln2 > 0) { if (ln1 > 0) ans -= lsum[dep + 1][l - 1 +ln1 + ln2] - lsum[dep + 1][l - 1 + ln1]; else ans -= lsum[dep + 1][l - 1 + ln2]; } int newr = R + toleft[dep][r] - toleft[dep][R]; int newl = newr - (R - L - cnt); return query(newl, newr, k - cnt, rson); } } int T;int n, m;int main(){ int x, y; cin >> T; int p = 1; while (T--) { RI(n);// CLR(t, 0,);///// CLR(toleft, 0);/// FE(i, 1, n) { RI(t[0][i]); st[i] = t[0][i]; } sort(st + 1, st + n + 1); build(1, n, 0);/// printf("Case #%d:\n",p++); RI(m); REP(i, m) { RII(x, y); x++; y++; ans = 0; LL midval = query(x, y, (y - x) / 2 + 1, 1, n, 0);///0 if ((y - x + 1) % 2 == 0) ans -= midval; cout << ans << endl; } printf("\n"); }}又一解法主要是lsum的处理不同
const int MAXN = 100010;const int MOD = 1000000;#define lson l, m, dep + 1#define rson m + 1, r, dep + 1int t[20][MAXN];int st[MAXN];int tol[20][MAXN];LL lsum[20][MAXN];LL ans;int n, m;void build(int l, int r, int dep){ if (l == r) { return ; } int m = (l + r) >> 1; int same = (m - l + 1); FE(i, l, r) if (st[m] > t[dep][i]) same--; int lpos = l; int rpos = m + 1; FE(i, l, r) { if (t[dep][i] < st[m]) t[dep + 1][lpos++] = t[dep][i]; else if (t[dep][i] == st[m] && same > 0) t[dep + 1][lpos++] = t[dep][i], same--; else t[dep + 1][rpos++] = t[dep][i]; tol[dep][i] = tol[dep][l - 1] + lpos - l; } FE(i, l, r) lsum[dep + 1][i] = lsum[dep + 1][i - 1] + t[dep + 1][i]; build(lson); build(rson);}LL query(int L, int R, int k, int l, int r, int dep){ if (L == R) return t[dep][L]; int m = (r + l) >> 1; int cnt = tol[dep][R] - tol[dep][L - 1]; int ln1 = tol[dep][L - 1] - tol[dep][l - 1]; int rn1 = L - l - ln1; int ln2 = cnt; int rn2 = R - L - cnt + 1; if (cnt >= k)//toleft { if (rn2 > 0) ans += lsum[dep + 1][m + rn2 + rn1] - lsum[dep + 1][m + rn1]; int newl = l + tol[dep][L - 1] - tol[dep][l - 1]; int newr = newl + cnt - 1; query(newl, newr, k, lson); } else//toright { if (ln2 > 0) ans -= lsum[dep + 1][l + ln2 + ln1 - 1] - lsum[dep + 1][l + ln1 - 1]; int newr = R + tol[dep][r] - tol[dep][R]; int newl = newr - (R - L - cnt); query(newl, newr, k - cnt, rson); }}int main(){ int T; RI(T); int x, y; int ncase = 1; while (T--) { RI(n); CLR(t, 0); CLR(lsum, 0); CLR(tol, 0); FE(i, 1, n) { RI(st[i]); t[0][i] = lsum[0][i] = st[i]; } sort(st + 1, st + n + 1); FE(i, 1, n) lsum[0][i] += lsum[0][i - 1]; build(1, n, 0); RI(m); printf("Case #%d:\n", ncase++); while (m--) { RII(x, y); x++; y++; ans = 0; int mid = query(x, y, (y - x) / 2 + 1, 1, n, 0); if ((y - x + 1) % 2 == 0) ans -= mid; cout << ans << endl; } cout << endl; }}
划分树hdu 4417SuperMario (求给定数在给定区间的中比它小的数的个数,或大小位置)(求逆序数)(通过修改query)(也可以二分答案!!!!!!!!!!!)
typedef long long LL;typedef unsigned long long ULL;typedef vector <int> VI;const int INF = 1000000000;const int maxn = 100010;const int deep = 20; #define lson l, m, dep + 1#define rson m + 1, r, dep + 1 int t[deep][maxn];int tol[deep][maxn];int st[maxn];int n;void build(int l, int r, int dep){ if (l == r) return; int m = (l + r) >> 1; int same = m - l + 1; FE(i, l, r) if (t[dep][i] < st[m]) same--; int lpos = l; int rpos = m + 1; FE(i, l, r) { if (t[dep][i] < st[m]) t[dep + 1][lpos++] = t[dep][i]; else if (t[dep][i] == st[m] && same > 0) { t[dep + 1][lpos++]= t[dep][i]; same--; } else t[dep + 1][rpos++] = t[dep][i]; tol[dep][i] = tol[dep][l - 1] + lpos - l; } build(lson); build(rson);} int ans;int h;void query(int L, int R, int l, int r, intdep){ if (L == R) { if (t[dep][L] <= h) ans++; return ; } int m = (l + r) >> 1; int cnt = tol[dep][R] - tol[dep][L - 1]; // int ln1 = tol[dep][L - 1] - tol[dep][l - 1];// int rn1 = L - l - ln1;//// int ln2 = cnt;// int rn2 = R - L - cnt + 1;//// int lr = t[dep + 1][l - 1 + ln1 + ln2];// int rl = t[dep + 1][m + rn1 + 1]; if (st[m] > h) { int newl = l + tol[dep][L - 1] - tol[dep][l - 1]; int newr = newl + cnt - 1; if (newl <= newr)///?!!!!!!!!!!! query(newl, newr, lson); } else { ans += cnt; int newr = R + tol[dep][r] - tol[dep][R]; int newl = newr - (R - L - cnt); if (newl <= newr)///?!!!!!!!!!!! query(newl, newr, rson); }} int T; int main(){ int x, y, z; int T; int p = 1; RI(T); while (T--) { //初始化 printf("Case %d:\n",p++); CLR(t, 0); CLR(tol, 0); int m; RII(n, m); FE(i, 1, n)/// { RI(t[0][i]); st[i] = t[0][i]; } sort(st + 1, st + n + 1); build(1, n, 0); while (m--) { RIII(x, y, z); h = z; ans = 0; query(++x, ++y, 1, n, 0); cout << ans << endl; } }}
- 划分树几道题目
- 划分树几道题目
- 子网划分题目
- 题目:链表划分
- 题目 10 划分数
- 题目90:整数划分
- 子网划分题目与解析
- 子网划分知识点及题目
- NYOJ 题目176整数划分(二)
- 南阳oj 题目 90 整数划分
- 南阳理工OJ_题目746 整数划分(四)
- NYOJ 题目176整数划分(二)(递归)
- POJ 题目2140 K-th Number(划分树)
- 51nod 1201:整数划分 超级好的DP题目
- 竞赛题目讲解-【Standard IO】数的划分
- 题目1103:区域赛系列一多边形划分
- 10.20 课件题目练习 贪心+MST+最短路+划分DP
- 划分
- NSObject:类与协议
- Js打印页面指定内容
- 虚拟盘符注册表项修改项
- ubuntu下编译安装openocd配合JLINK调试
- 调用函数的方式决定了调用的上下文中的this值
- 划分树几道题目
- Myeclipse下安装Ext-js插件(亲测)
- shell -e -d等参数说明
- Linux之fdisk -l命令
- Tomcat 启动时出现java.io.EOFException
- eclipse cdt 使用其他主题导致 elif 宏 代码库 看不清问题
- 一个公司的管理之六:试用期不能要的几种人
- cocos2d-x2.2九宫格CCScale9Sprite有bug
- 深入研究B树索引(一)