HDU 4614 (13年多校第二场1004)裸线段树
题意:给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每个花瓶最多插一朵花。
然后有2个操作。
操作1,a b c ,往在a位置后面(包括a)插b朵花,输出插入的首位置和末位置。
操作2,a b ,输出区间[a , b ]范围内的花的数量,然后全部清空。
很显然这是一道线段树。区间更新,区间求和,这些基本的操作线段树都可以logN的时间范围内完成。
操作2,很显然就是线段树的区间求和,求出[a , b]范围内的花朵的数量,区间更新,将整个区间全部变成0。
操作1,这里我们首先需要找出他的首位置和末位置,所以需要二分他的位置。
首先我们二分他的首位置, l = a , r = n ,在这个区间内二分,找出第一个0的位置,那就是该操作的首位置pos1。
然后再二分他的末位置,l = pos1 , r = n ,找到第b个0,就是该操作的末位置pos2,然后区间更新[pos1 ,pos2]全部置为1。
就像解题报告上讲的一样,这是一道很裸的线段树。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2505
#define inf 1<<28
#define LL(x) ( x << 1 )
#define RR(x) ( x << 1 | 1 )
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define PII pair<int,int>
using namespace std;
#define M 150005 inline void RD(int &ret) {
char c;
do {
c = getchar();
} while(c < '0' || c > '9') ;
ret = c - '0';
while((c=getchar()) >= '0' && c <= '9')
ret = ret * 10 + ( c - '0' );
}
int n , m ;
int L[M] , R[M] , sum[M] ,add[M] ; void init(){
mem(sum ,0) ;
mem(add, 0) ;
}
void push_up(int x){
sum[x] = sum[LL(x)] + sum[RR(x)] ;
}
void push_down(int x){
if(L[x] == R[x])return ;
if(add[x] == 1){//全部置为1
sum[x] = R[x] - L[x] + 1 ;
sum[LL(x)] = R[LL(x)] - L[LL(x)] + 1 ;
sum[RR(x)] = R[RR(x)] - L[RR(x)] + 1 ;
add[LL(x)] = add[x] ;
add[RR(x)] = add[x] ;
add[x] = 0 ;
}
else if(add[x] == 2){//全部置为0
sum[x] = 0 ;
sum[LL(x)] = 0 ;
sum[RR(x)] = 0 ;
add[LL(x)] = add[x] ;
add[RR(x)] = add[x] ;
add[x] = 0 ;
}
}
void build(int l , int r ,int u){
L[u] = l ;
R[u] = r ;
sum[u] = 0 ;
add[u] = 0 ;
if(l == r)return ;
int mid = l + r >> 1 ;
build(l , mid ,LL(u)) ;
build(mid + 1 ,r ,RR(u)) ;
} void update(int l ,int r ,int u ,int op){
if(l > R[u] || r < L[u])return ;
push_down(u) ;
if(l == L[u] && r == R[u]) {
if(op == 1)
sum[u] = R[u] - L[u] + 1 ;
else sum[u] = 0 ;
add[u] = op ;
return ;
}
int mid = L[u] + R[u] >> 1 ;
if(r <= mid){
update(l ,r ,LL(u) , op) ;
}
else if(l > mid){
update(l , r , RR(u),op) ;
}
else {
update(l , mid ,LL(u),op) ;
update(mid + 1 , r , RR(u) ,op) ;
}
push_up(u) ;
}
int query(int l ,int r ,int u){
if(l > R[u] || r < L[u])return 0 ;
push_down(u) ;
if(l == L[u] && r == R[u]) {
return sum[u] ;
}
int mid = L[u] + R[u] >> 1 ;
if(r <= mid){
return query(l , r, LL(u)) ;
}
else if(l > mid){
return query(l , r ,RR(u)) ;
}
else {
return query(l , mid , LL(u)) + query(mid + 1 , r , RR(u)) ;
}
}
void Noanswer(){
puts("Can not put any one.") ;
}
void answer(int p1, int p2){
printf("%d %d\n",p1, p2) ;
}
void answer(int p){
printf("%d\n",p) ;
}
void debug(int u){ printf(" 节点 %d 区间 : %d - %d \n" , u ,L[u] ,R[u]) ;
printf(" 左子树 %d 右子树 %d \n" , LL(u) ,RR(u) ) ;
printf("父节点sum值:%d\n",sum[u]) ;
push_down(u) ;
if(L[u] == R[u])return ;
debug(LL(u)) ;
debug(RR(u)) ;
}
void solve1(int a , int b){
int pos1 = inf ;
int l = a , r = n ;
int nn = n - a + 1 - query(a , n , 1) ;
if(!nn){//如果区间内没有0的位置了,那么就直接输出。
Noanswer() ;
return ;
}
while(r >= l){//二分首位置
int mid = l + r >> 1 ;
int now = mid - a + 1 - query(a ,mid ,1) ;
if(now >= 1){
pos1 = min(pos1 ,mid) ;
r = mid - 1 ;
}
else l = mid + 1 ;
}
int pos2 = inf ;
nn = n - pos1 + 1 - query(pos1 , n ,1) ;
if(nn <= b){//如果剩余的0的个数小于等于b的数量,那么需要找出最后一个0的位置。
int l = pos1 , r = n ;
while(r >= l){//二分末位置
int mid = r + l >> 1 ;
int now = mid - pos1 + 1 - query(pos1 , mid , 1) ;
if(now == nn){
pos2 = min(pos2 , mid) ;
r = mid - 1 ;
}
else l = mid + 1 ;
}
answer(pos1 - 1, pos2 - 1) ;
update(pos1, pos2 , 1 , 1) ;
}
else {//其实我觉得这个二分和上面那个可以合并的,我懒得改了。
int l = pos1 , r = n ; while(r >= l){//二分末位置
int mid = l + r >> 1 ;
int now = mid - pos1 + 1 - query(pos1, mid, 1) ;
if(now == b){
pos2 = min(pos2 ,mid) ;
r = mid - 1 ;
}
else if(now > b)r = mid - 1 ;
else l = mid + 1 ;
}
answer(pos1 - 1, pos2 - 1 ) ;
update(pos1 ,pos2 ,1, 1) ;
}
}
void solve2(int a , int b){
answer(query(a , b , 1)) ;
update(a , b, 1 , 2) ;
}
int main() {
int T ;
cin >> T ;
int ss = 0 ;
while( T -- ){
scanf("%d%d",&n,&m) ;
init() ;
build(1 ,n , 1) ;
while(m -- ){
//debug(1) ;
int a , b , c ;
RD(a) ;
RD(b) ;
RD(c) ;
if(a == 1){
b ++ ;
solve1(b , c) ;
}
else if(a == 2){
b ++ , c ++ ;
solve2(b , c) ;
}
}
puts("") ;
}
return 0 ;
}
HDU 4614 (13年多校第二场1004)裸线段树的更多相关文章
- MAZE(2019年牛客多校第二场E题+线段树+矩阵乘法)
题目链接 传送门 题意 在一张\(n\times m\)的矩阵里面,你每次可以往左右和下三个方向移动(不能回到上一次所在的格子),\(1\)表示这个位置是墙,\(0\)为空地. 现在有\(q\)次操作 ...
- HDU 4612 (13年多校第二场1002)无向图缩点,有重边
这道题是多校的题,比赛的时候是一道纷纷水过的板刷题. 题意:给你一些无向边,只加一条边,使该图的桥最少,然后输出最少的桥. 思路:当时大致想到思路了,就是缩点之后找出最长的链,然后用总的桥数减去链上的 ...
- hdu 5308 (2015多校第二场第9题)脑洞模拟题,无语
题目链接:http://acm.hdu.edu.cn/listproblem.php?vol=44 题意:给你n个n,如果能在n-1次运算之后(加减乘除)结果为24的输出n-1次运算的过程,如果不能输 ...
- hdu 5301 Buildings (2015多校第二场第2题) 简单模拟
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5301 题意:给你一个n*m的矩形,可以分成n*m个1*1的小矩形,再给你一个坐标(x,y),表示黑格子 ...
- 【HDU 5305】Friends 多校第二场(双向DFS)
依据题意的话最多32条边,直接暴力的话 2 ^ 32肯定超时了.我们能够分两次搜索时间复杂度降低为 2 * 2 ^ 16 唯一须要注意的就是对眼下状态的哈希处理. 我採用的是 十进制表示法 跑的还是 ...
- 多校第二场 1004 hdu 5303 Delicious Apples(背包+贪心)
题目链接: 点击打开链接 题目大意: 在一个周长为L的环上.给出n棵苹果树.苹果树的位置是xi,苹果树是ai,苹果商店在0位置,人的篮子最大容量为k,问最少做多远的距离可以把苹果都运到店里 题目分析: ...
- hdu 6053: TrickGCD (2017 多校第二场 1009) 【莫比乌斯 容斥原理】
题目链接 定义f[n]表示n是最大公约数情况下的计数,F[n]为n是公约数情况下的计数 (可以和 http://www.cnblogs.com/Just--Do--It/p/7197788.html ...
- HDU6312 Game (多校第二场1004) 简单博弈
Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- hdu6312 2018杭电多校第二场 1004 D Game 博弈
Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
随机推荐
- 嵌入式 现已发展为 IT行业的主流——高薪,且人才缺乏
嵌入式 现已发展为 IT行业的主流——高薪,且人才缺乏 硅谷芯微技术中心,注重实践操作,以实际项目带学员,让学员真正学到东西,达到企业用人标准,有兴趣的,可以前来了解,给自己多一个选择的机会,可以多家 ...
- ionic中使用Cordova Uglify 压缩js与css
参照:https://www.npmjs.com/package/cordova-uglify 安装:npm install cordova-uglify 安装完成之后,打开: hooks/uglif ...
- keil c编译器错误与解决方法
1. Warning 280:’i’:unreferenced local variable 说明局部变量i 在函数中未作任何的存取操作解决方法消除函数中i 变量的宣告 2 Warning 206:’ ...
- COCI2014-2015CONTEST#7——POLICE
http://www.hsin.hr/coci/archive/2014_2015/contest7_tasks.pdf [题目描述] 有N个书架,每个书架可以容纳M本书.给出了若干本书,每本书有一个 ...
- 舶来品P2P理财 能否成为“好声音”式好生意? 转
华股财经 2012年11月29日 10:20:02 来源:互联网 字号:T|T 文/本刊记者 王奇 有数据显示,目前国内已有2000余家P2P公司,2007年至2011年上半年,其整体融资规模由2 ...
- DatabaseMetaData的用法【转载】
一 . 得到这个对象的实例Connection con ;con = DriverManager.getConnection(url,userName,password);DatabaseMetaDa ...
- [Java] 继承中,父类被覆盖的成员变量、方法的可访问性
在 Java 的继承机制里,在子类内部,可以访问父类被覆盖的变量和方法:在子类外部,可以访问父类的被覆盖变量,但是不能访问父类的被覆盖方法. 父类中被覆盖的方法不能在外部被方法,这是出于封装的考虑. ...
- 跟Google学习Android开发-起始篇-用碎片构建一个动态的用户界面(3)
4.3 构建一个灵活的用户界面 当设计你的应用程序要支持大范围的屏幕尺寸时,你可以在不同的布局配置中重用碎片,来根据可用的屏幕空间优化用户体验. 例如,在手持设备上,它可能是适应来在一个单窗格用户界面 ...
- SKKeyframeSequence类
继承自 NSObject 符合 NSCodingNSCopyingNSObject 框架 /System/Library/Frameworks/SpriteKit.framework 可用性 可用于 ...
- LeetCode Maximum Product Subarray 解题报告
LeetCode 新题又更新了.求:最大子数组乘积. https://oj.leetcode.com/problems/maximum-product-subarray/ 题目分析:求一个数组,连续子 ...