hdu4614 二分法+段树
2024-08-31 22:15:36
意甲冠军:给你1-n花瓶 。起初,所有的空,今天,有两种操作模式,
1:从花瓶a開始插入b朵花 假设不能插进去 输出字符串 否则输出最多插入的起点和终点;
2:把a-b的花瓶清空 输出处理花的个数;
结构体数组num【i】表示节点i空瓶的数目
线段树 開始deal函数对整个树初始化,update()更新函数 find()查询区间有多少个空瓶; 对于操作1 关键点是找到起点和终点 这里用二分 在【a,n】进行二分,
先二分起点 注意左右区间的变换(wa了好多次==) 然后在起点和n之间二分终点 最后更新 输出 对于操作2 直接查询就可以;
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std; #define LL(x) (x<<1)
#define RR(x) ((x<<1)|1)
struct node
{
int cont;
}num[50000*4];
int deal(int L,int R,int point)
{
num[point].cont=R-L+1;
if(L==R) return 0;
int mid=(L+R)/2;
deal(L,mid,LL(point));
deal(mid+1,R,RR(point));
return 0;
}
int update(int L,int R,int left,int right,int point,int k)
{
if(L==left&&R==right)
{
if(k==1) num[point].cont=R-L+1;
else num[point].cont=0;
return 0;
}
int mid=(L+R)/2;
if(num[point].cont==R-L+1)
{
num[LL(point)].cont=mid-L+1;
num[RR(point)].cont=R-mid;
}
if(num[point].cont==0)
{
num[LL(point)].cont=0;
num[RR(point)].cont=0;
}
if(right<=mid)
{
update(L,mid,left,right,LL(point),k);
}
else if(left>mid)
{
update(mid+1,R,left,right,RR(point),k);
}
else
{
update(L,mid,left,mid,LL(point),k);
update(mid+1,R,mid+1,right,RR(point),k);
}
num[point].cont=num[LL(point)].cont+num[RR(point)].cont;
return 0;
}
int find(int L,int R,int left,int right,int point)
{
if(L==left&&R==right)
return num[point].cont;
int sum=0;
int mid=(L+R)/2;
if(num[point].cont==R-L+1) return right-left+1;
if(num[point].cont==0) return 0;
if(right<=mid) sum+=find(L,mid,left,right,LL(point));
else if(left>mid) sum+=find(mid+1,R,left,right,RR(point));
else
{
sum+=find(L,mid,left,mid,LL(point));
sum+=find(mid+1,R,mid+1,right,RR(point));
}
return sum;
}
int main()
{
int n,m,k,i,j,T,a,b;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
deal(1,n,1);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&k,&a,&b);
if(k==1)
{
a+=1;
int cont=find(1,n,a,n,1);
if(cont==0) printf("Can not put any one.\n");
else
{
int left,right,mid;
int star,end;
left=a;
right=n;
while(left<=right)
{
mid=(left+right)/2;
if(find(1,n,left,mid,1)>0)
{
right=mid-1;
star=mid;
}
else left=mid+1; }
if(cont<=b)
{
left=a;
right=n;
while(left<=right)
{
mid=(left+right)/2;
if(find(1,n,mid,right,1)>0)
{
left=mid+1;
end=mid;
}
else right=mid-1;
}
//end=right;
}
else
{
left=a;
right=n;
while(left<=right)
{
mid=(left+right)/2;
if(find(1,n,star,mid,1)>=b)
{
right=mid-1;
end=mid;
}
else left=mid+1;
}
//end=left;
}
printf("%d %d\n",star-1,end-1);
update(1,n,star,end,1,-1);
}
}
else
{
printf("%d\n",b-a+1-find(1,n,a+1,b+1,1));
update(1,n,a+1,b+1,1,1);
} }
printf("\n");
}
return 0;
}
最新文章
- cctype头文件中的一些内容
- Javascript高级程序设计——基本概念(一)
- google maps js v3 api教程(2) -- 在地图上添加标记
- 命令行bash的基础操作
- js 日常问题记录
- 如何测试sql语句性能,提高执行效率
- android Listview,gridview局部刷新,部分刷新
- arcconf
- Struts2笔记分享(一)
- SourceInSight自定义命令说明与应用
- Win10 开启移动热点 WiFi 的简单方法
- POJ 3264 Balanced Lineup 【线段树】
- js模拟散列
- 技术实战:基于 MHA 方式实现 MySQL 的高可用(转)
- spring 事物管理没起到作用
- SpringBoot整合JdbcTemplate连接Mysql
- QList和QVector使用
- LeetCode OJ:Merge k Sorted Lists(归并k个链表)
- jQuery样式与动画
- 上传文件提示413 Request Entity Too Large错误
热门文章
- 超级简单的Android Studio jni 实现(无需命令行)
- Android JNI--基础篇(二)
- APPCAN学习笔记002---app高速开发AppCan.cn平台特色
- SignalR+NAudio实现语音会话[WPF]
- NotifyICon使用
- HDU 树型dp
- 怎样获取android手机联系人并按字母展示(三)
- mingw-w64线程模型:posix vs win32(posix允许使用c++11的std:: thread,但要带一个winpthreads,可能需要额外dll)
- AndroidStudio封装SDK的那些事
- Lettcode_104_Maximum Depth of Binary Tree