[luoguP3960] 列队(动态开点线段树)
有splay的做法,有树状数组的做法。。。
最好理解的还是线段树的做法。
一开始我是这样想的,如果移动某一个人,只有当前行和最后一列会受到影响,感觉就像是个线段树,树状数组什么的。
然而接下来就想歪了,把一个人移到后面,等于把后面的整体往前移一格,gg
正确思路是权值线段树,如果一个数被移走,相当于这个数的个数-1,然后把它变成了m+1,放到后面。
移动第x行第y个人其实就是求第x行的第y大。
这样,每一行和最后一列建一棵线段树,然而超空间。
所以需要动态开点,因为总共只移动3*10^5次,也就是开nlongn的点。
据说逆向思维可以骗50分,这都没想到。。。
最后附上丑陋的,调了一晚上的,连我自己都看不懂的代码——
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 600001
#define LL long long using namespace std; int n, m, q, M, cnt;
int size[N], sum[N * 10], ls[N * 10], rs[N * 10], root[N];
LL val[N * 10]; inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
} inline LL del(int &now, int l, int r, int x, int f, int h)
{
if(!now) now = ++cnt;
sum[now]--;
if(l == r)
{
if(!f) return val[now] ? val[now] : (LL)(h - 1) * m + l;
return val[now] ? val[now] : (LL)l * m;
}
int mid = (l + r) >> 1;
if(mid - l + 1 + sum[ls[now]] >= x) return del(ls[now], l, mid, x, f, h);
else return del(rs[now], mid + 1, r, x - (mid - l + 1 + sum[ls[now]]), f, h);
} inline void insert(int &now, int l, int r, int x, LL d)
{
if(!now) now = ++cnt;
if(l == r)
{
val[now] = d;
return;
}
int mid = (l + r) >> 1;
if(x <= mid) insert(ls[now], l, mid, x, d);
else insert(rs[now], mid + 1, r, x, d);
} int main()
{
int i, x, y;
LL a, b;
n = read();
m = read();
q = read();
M = max(n, m) + q;
size[0] = n;
for(i = 1; i <= n; i++) size[i] = m - 1;
while(q--)
{
x = read();
y = read();
if(y != m) a = del(root[x], 1, M, y, 0, x);
b = del(root[0], 1, M, x, 1, x);
printf("%lld\n", y == m ? a = b : a);
if(y != m)
{
++size[x];
insert(root[x], 1, M, size[x], b);
}
++size[0];
insert(root[0], 1, M, size[0], a);
}
return 0;
}
就让这个题作为我回归奥赛的开端,SDOI2018加油!
[luoguP3960] 列队(动态开点线段树)的更多相关文章
- Luogu P3960 列队(动态开点线段树)
P3960 列队 题意 题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有\(n \times m ...
- NOIP2017 列队——动态开点线段树
Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为 ...
- 洛谷P3960 列队(动态开节点线段树)
题意 题目链接 Sol 看不懂splay..,看不懂树状数组... 只会暴力动态开节点线段树 观察之后不难发现,我们对于行和列需要支持的操作都是相同的:找到第\(k\)大的元素并删除,在末尾插入一个元 ...
- [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)
题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...
- 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化
4636: 蒟蒻的数列 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 247 Solved: 113[Submit][Status][Discuss ...
- codeforces 893F - Physical Education Lessons 动态开点线段树合并
https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...
- codeforces 915E - Physical Education Lessons 动态开点线段树
题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...
- CF915E Physical Education Lessons 动态开点线段树
题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include&l ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
随机推荐
- nGrinder技术架构图
- MySQL存储过程简介和引擎说明
- 通过90行代码学会HTML5 WebSQL的4种基本操作
Web SQL数据库API是一个独立的规范,在浏览器层面提供了本地对结构化数据的存储,已经被很多现代浏览器支持了. 我们通过一个简单的例子来了解下如何使用Web SQL API在浏览器端创建数据库表并 ...
- UVA 12549 Sentry Robots (最小点覆盖)
这道题挺像hdu 5093 Battle ships的,不过那道题是要求最多放置的点数,而这道题是要求最小点覆盖. 顶点覆盖的定义是:在G中任意边至少有一个端点属于顶点集合S. 一个重要的位置有(x, ...
- 适用于iOS7 UI的外描边图标素材下载
我们知道ios7的界面设计是非常简约的,图标也不例外,iOS7的icon大部使用了扁平化的外描边风格设计,使得整体看起来十分简约.耐看,这次分享达人为大家收集将近600个漂亮的外描边图标下载,这些图标 ...
- Airbnb:别抵制我,宝宝要过 10 岁生日
今日导读 喜欢旅游的你,一定听说或使用过 airbnb(爱彼迎),在出发前打开它,总是能通过它开始一段奇妙的旅行.可是最近,就在这个打着“共享家”概念的服务型网站正迎来十周年之际,它却遭到了很多国家的 ...
- Bootstrap-datepicker设置开始时间结束时间范围
$('.form_datetime').datepicker({ format: 'yyyy-mm-dd', weekStart: 1, startDate: '+1', endD ...
- vue父组件获取子组件页面的数组 以城市三级联动为例
父组件调用子组件 <Cselect ref="registerAddress"></Cselect> import Cselect from '../../ ...
- web前端常用的封装方法
1.放大镜 //页面加载完毕后执行 window.onload = function () { var oDemo = document.getElementById('demo'); var oMa ...
- 【php】 php 的注释和结束符号之间的关系
Closing PHP tags are recognised within single-line comments: <?php // Code will end here ?> ...