noip2017D2T3的几种写法...(BIT/线段树/平衡树)
题意各大oj上都有啦..想必来搜题解的都看过题面了...Qw
Solution1:
首先观察n=1的情况,显然就是中间删掉一个数后面加上一个数,并查询那个删掉的数(以后把这样一个过程称为一个操作啦((:)..
就是你用什么都可以写..
然后发现,完整的数据范围就是n+1个n=1的子问题
就是前n行每行前m-1个数的n个子问题和最后一列的子问题..(有点乱乱啊..语文差..
然而开n+1棵什么什么树肯定MLE.....下面以线段树为例
:注意到一次操作,最多更改2log(n)个点,于是就可以愉快动态开点啦(^:
(稍稍借鉴了一下jxc的写法,,好短好妙妙啊
#include<bits/stdc++.h>
using namespace std; const int M = ; struct Node{
Node *lc, *rc;
int l, r, val;
Node(int l = , int r = M << ) {
this->lc = this->rc = NULL;
this->l = l;
this->r = r;
this->val = r - l + ;
}
}; struct SegTree{
Node *rt;
vector<long long> add;
SegTree(void) {
rt = new Node();
add.clear();
}
int Del(Node *p, int x) {
p->val--;
if(p->l == p->r) return p->l;
int mid = (p->l + p->r) >> ;
int lcv = p->lc ? p->lc->val : mid - p->l + ;
if(lcv >= x) {
if(!p->lc) p->lc = new Node(p->l, mid);
return Del(p->lc, x);
} else {
if(!p->rc) p->rc = new Node(mid + , p->r);
return Del(p->rc, x - lcv);
}
}
}line[M + ], row; int n, m, q, x, y;
long long now; int main(void) {
scanf("%d%d%d", &n, &m, &q);
while(q--) {
scanf("%d%d", &x, &y);
int id = row.Del(row.rt, x);
if(id <= n) now = 1LL * id * m;
else now = row.add[id - n - ];
if(y != m) {
line[x].add.push_back(now);
int id = line[x].Del(line[x].rt, y);
if(id < m) now = 1LL * (x - ) * m + id;
else now = line[x].add[id - m];
}
row.add.push_back(now);
printf("%lld\n", now);
}
return ;
}
Solution2:
注意到BIT不能动态开点(至少我不会啊ov
于是考虑离线,稍微思考一下,,,,于是发现每一行的查询是独立的,也就是说可以离线之后只开一个BIT
然后把每一行处理完之后再扔回去就可以保证所有行的查询操作是log的
这样就预处理完啦
剩下的就跟之前的一样做就行了(包括那一列的(因为那一列的操作每次都有啊..
#include<bits/stdc++.h>
using namespace std; const int M = ; int val[M << ];
vector<pair<int, int> > query[M]; inline void Add(int x, int y) {
for(; x <= M << ; x += -x & x) val[x] += y;
} inline int Qry(int x) {
int res = ;
for(int i = ; i >= ; i--)
if(( << i) + res <= (M << )) {
if(val[res + ( << i)] < x) {
res += << i;
x -= val[res];
}
}
return res + ;
} void Get_num(int *a, int x) {
for(int i = ; i < query[x].size(); i++) {
pair<int, int> o = query[x][i];
a[o.second] = Qry(o.first);
Add(a[o.second], -);
}
for(int i = ; i < query[x].size(); i++) {
pair<int, int> o = query[x][i];
Add(a[o.second], );
}
} long long now;
vector<long long> last[M];
int n, m, q, x, y, qx[M], qy[M], row[M]; int Read(void) {
int x = ; char ch = getchar();
while(ch < '' || ch > '') ch = getchar();
while(ch <= '' && ch >= '') x = x * + ch - '', ch = getchar();
return x;
} int main(void) {
scanf("%d%d%d", &n, &m, &q);
for(int i = ; i <= q; i++) {
x = Read(); y = Read();
if(y != m) query[x].push_back(make_pair(y, i));
qx[i] = x, qy[i] = y;
} for(int i = ; i <= M << ; i++)
Add(i, );
for(int i = ; i <= n; i++)
Get_num(row, i); for(int i = ; i <= q; i++) {
int id = Qry(qx[i]);
Add(id, -);
if(id <= n) now = 1LL * id * m;
else now = last[][id - n - ];
if(qy[i] < m) {
last[qx[i]].push_back(now);
int id = row[i];
if(id < m) now = 1LL * (qx[i] - ) * m + id;
else now = last[qx[i]][id - m];
}
last[].push_back(now);
printf("%lld\n", now);
}
return ;
}
Solution3:
据说可以trie做.....不会...
noip2017D2T3的几种写法...(BIT/线段树/平衡树)的更多相关文章
- 洛谷 P3919 【模板】可持久化数组(可持久化线段树/平衡树)-可持久化线段树(单点更新,单点查询)
P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目背景 UPDATE : 最后一个点时间空间已经放大 标题即题意 有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集 ...
- 洛谷——P3919 【模板】可持久化数组(可持久化线段树/平衡树)
P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目背景 UPDATE : 最后一个点时间空间已经放大 标题即题意 有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集 ...
- Luogu P3919【模板】可持久化数组(可持久化线段树/平衡树)
题面:[模板]可持久化数组(可持久化线段树/平衡树) 不知道说啥,总之我挺喜欢自己打的板子的! #include<cstdio> #include<cstring> #incl ...
- luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)
luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目 #include<iostream> #include<cstdlib> #include< ...
- cf1132G 线段树解分区间LIS(一种全新的线段树解LIS思路)+单调栈
/* 给定n个数的数列,要求枚举长为k的区间,求出每个区间的最长上升子序列长度 首先考虑给定n个数的数列的LIS求法:从左往右枚举第i点作为最大点的贡献, 那么往左找到第一个比a[i]大的数,设这个数 ...
- BZOJ 1146: [CTSC2008]网络管理Network 树链剖分+线段树+平衡树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 870 Solved: 299[Submit] ...
- Bzoj 1901: Zju2112 Dynamic Rankings 树套树,线段树,平衡树,Treap
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6471 Solved: 2697[Su ...
- CF 19D Points 【线段树+平衡树】
在平面上进行三种操作: 1.add x y:在平面上添加一个点(x,y) 2.remove x y:将平面上的点(x,y)删除 3.find x y:在平面上寻找一个点,使这个点的横坐标大于x,纵坐标 ...
- P3919 【模板】可持久化数组(可持久化线段树/平衡树)
题目描述 如题,你需要维护这样的一个长度为 N 的数组,支持如下几种操作 在某个历史版本上修改某一个位置上的值 访问某个历史版本上的某一位置的值 此外,每进行一次操作(对于操作2,即为生成一个完全一 ...
随机推荐
- Google Chrome 未响应。是否立即重新启动?
不当的退出会造成 Google Chrome 无法启动.出现“Google Chrome 未响应.是否立即重新启动?”的错误.要解决这个问题: 1.同时按住Windows旗帜键 + R键,调 ...
- ML 线性回归Linear Regression
线性回归 Linear Regression MOOC机器学习课程学习笔记 1 单变量线性回归Linear Regression with One Variable 1.1 模型表达Model Rep ...
- 在移动端做查看日志信息的js
Vconsole.js下载这个js引入需要使用的html文件,当运行到页面是就会在右下角显示提示,点击就出出现像pc端上的控制台页面 在线查看的网址 http://console.hongliang. ...
- 解决Android7.1.1中无法打开/data目录的问题
声明:本技巧借鉴https://segmentfault.com/a/1190000008416511这个大神的文章 一.复制android Sdk安装目录的platform-tools路径: 二.w ...
- 查找和删除倒数第n个节点的问题
class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public class NthNodeFromEnd ...
- Thinkpad个性化设置:F1~F12恢复正常按键,Fn与Ctrl按键互换
一.F1~F12恢复正常按键 联想Thinkpad的F1~F12键功能与其他笔记本是相反的! 也就是说,如果不按着Fn,按那几个功能键,实现的是属性设置的功能,比如直接按下F1键是静音,F2键是音量降 ...
- C#验证类
#region 是不是中国电话,格式010-85849685 /**////<summary> /// 是不是中国电话,格式010-85849685 ///</summary> ...
- VMware Workstation Pro v14.0
早些时候戴尔旗下的虚拟化软件 VMware Pro v14 版正式发布,本次更新主要是优化对创意者更新版的支持. 创意者更新版是目前微软 Windows 10 系统的最新版本,该版本亦会在十月份成为C ...
- splunk的统计分析功能——特定字段的统计功能包括取值分布(+topK,min/max/平均值)
特定字段的统计功能——取值分布,topK,min/max/平均值 例如: date_second 60 值, 100% 的事件 时段平均值 时段最大值 时段最小值 上限值 时段上限值 罕见值 具有此字 ...
- UVA - 11014 Make a Crystal (莫比乌斯反演)
给定一个n*n*n的立方体(中心点为原点O),选择尽量多的点,使得对于任意两点A,B,B不在线段OA上. 可以发现,原问题可转化为三维坐标下的点(x,y,z)中有多少个点的gcd(x,y,z)=1. ...