uva 12356 Army Buddies 树状数组解法 树状数组求加和恰为k的最小项号 难度:1
Nlogonia is fighting a ruthless war against the neighboring country of Cubiconia. The Chief General of Nlogonia's Army decided to attack the enemy with a linear formation of soldiers, that would advance together until conquering the neighboring country. Before the battle, the Chief General ordered that each soldier in the attack line, besides protecting himself and attacking, should also protect his two (nearest) neighbors in the line, one to his left and one to his right. The Chief General told the soldiers that for each of them, his ``buddies" would be these two neighbors, if such neighbors existed (because the leftmost soldier does not have a left neighbor and the rightmost soldier does not have a right neighbor). The Chief General also told the soldiers that protecting their buddies was very important to prevent the attack line from being broken. So important that, if the left or right buddy of a soldier is killed, then the next living neighbor to the left or to the right of the soldier, respectively, should become his buddy.
The battle is fierce, and many soldiers in the attack line are being killed by fire shots, grenades and bombs. But following the Chief General's orders, immediately after knowing about losses in the attack line, the Army's information systems division has to inform the soldiers who their new buddies are.
You are given the number of soldiers in the attack line, and a sequence of loss reports. Each loss report describes a group of contiguous soldiers in the attack line that were just killed in the battle. Write a program that, for each loss report, prints the new buddies formed.
Input
Each test case is described using several lines. The first input line contains two integers S and Brepresenting respectively the number of soldiers in the attack line, and the number of loss reports ( 1BS105). Soldiers are identified by different integers from 1 to S, according to their positions in the attack line, being 1 the leftmost soldier and S the rightmost soldier. Each of the next B input lines describes a loss report using two integers L (left) and R (right), meaning that soldiers from L to R were killed ( 1LRS). You may assume that until that moment those soldiers were alive and were just killed.
The last test case is followed by a line containing two zeros.
Output
For each test case output B + 1 lines. In the i-th output line write the new buddies formed by removing from the attack line the soldiers that were just killed according to the i-th loss report. That is, for the loss report `L R', print the first surviving soldier to the left of L, and the first surviving soldier to the right of R. For each direction, print the character `*' (asterisk) if there is no surviving soldier in that direction. Print a line containing a single character `-' (hyphen) after each test case.
Sample Input
1 1
1 1
10 4
2 5
6 9
1 1
10 10
5 1
1 1
0 0
Sample Output
* *
-
1 6
1 10
* 10
* *
-
* 2
-
这道题一开始想用线段树来做,然后改成了树状数组,结果发现就不应该用树状数组做,那个悬在超时边上
经验教训:不可以用dat[k]!=0判断第k位置的人没有被杀,这个值可能是比它小的人贡献的
思路: 每个位置都是1,被杀了就变成0,因为每个人只杀一次,所以顶多被杀10^5次,这个即使按人更新都可以承受,所以就干脆分开从L到R的闭区间的每个点杀了都更新成0;对于一整个区间,因为都是0,所以sum(0,i)(i属于区间中的下标)都是相等的;而左边的没被杀的人恰好是等于这个值的第一个序号,右边没被杀的人是等于这个值+1的第一个序号,用来求sum(0,i)当然是树状数组
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e5+2;
int s,b;
int dat[maxn<<1];
int lowbit(int k ){
return k&(-k);
}
void update(int k,int a){
if(k<0||dat[k]+a<0)return ;
while(k<=s){
dat[k]+=a;
k+=lowbit(k);
}
}
int query(int k){
int ans=0;
while(k>0){
ans+=dat[k];
k-=lowbit(k);
}
return ans;
}
int getk(int k){//找到和恰为k的第一个点,返回值小于等于n,大于等于1
if(k<0)return 0;
int ans=0,cnt=0;
for(int i=25;i>=0;i--){
ans+=(1<<i);
if(ans>=s||cnt+dat[ans]>=k)ans-=(1<<i);
else cnt+=dat[ans];
}
return ans+1;
}
int main(){
while(scanf("%d%d",&s,&b)==2&&s&&b){
//for(int i=1;i<=s;i++)update(i,-1);这个不行
memset(dat,0,sizeof(int)*2*n);
for(int i=1;i<=s;i++)update(i,1);//初始化
for(int i=0;i<b;i++){
int l,r;
scanf("%d%d",&l,&r);
for(int i=l;i<=r;i++)update(i,-1);//减人
int tmp=query(r);//查询这个区间前面剩余人数
int pos1=getk(tmp);//找到左端点
int pos2=getk(tmp+1);//找到右端点
if(query(pos2)!=tmp+1)pos2++;//因为这个算法不会超过n,为了判断最后一个人是否存在
if(query(pos1)==0)putchar('*');
else printf("%d",pos1);
putchar(' ');
if(pos2>s)putchar('*');
else printf("%d",pos2);
putchar('\n');
}
puts("-");//分割case
}
return 0;
}
uva 12356 Army Buddies 树状数组解法 树状数组求加和恰为k的最小项号 难度:1的更多相关文章
- uva 12356 Army Buddies
简单的并查集应用. #include<stdio.h> #include<string.h> #include<math.h> #include<algori ...
- Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)(值域线段树第k大)
Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序 ...
- 差分+树状数组 线段树【P2357】 守墓人
题目描述-->p2357 守墓人 敲了一遍线段树,水过. 树状数组分析 主要思路: 差分 简单介绍一下差分(详细概念太麻烦,看下面. 给定一个数组 7 8 6 5 1 8 18 20 35 // ...
- hdu 1166 树状数组(线段树)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]
题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...
- 【BZOJ-1452】Count 树状数组 套 树状数组
1452: [JSOI2009]Count Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1769 Solved: 1059[Submit][Stat ...
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...
随机推荐
- springCloud--1
电影微服务是服务消费者,用户微服务是服务提供者. Springcloud对eureka的支持很好,eureka本身是一个基于REST的服务, Eureka里面有一个注册表,Application Cl ...
- PHP开发之apache mac上配置
我使用的Mac OS X版本是10.8.2,Mac自带了Apache环境. 启动Apache 设置虚拟主机 启动Apache 打开“终端(terminal)”,输入 sudo apachectl -v ...
- Windows下编译live555源码
Windos下编译live555源码 环境 Win7 64位 + VS2012 步骤 1)源码下载并解压 在官网上下载最新live555源码,并对其进行解压. 2)VS下建立工程项目 新建Win32项 ...
- vmware 虚拟机三种网卡
转:https://blog.csdn.net/lyf_ldh/article/details/78695357 vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式).NA ...
- Django学习笔记之Django QuerySet的方法
一般情况下,我们在写Django项目需要操作QuerySet时一些常用的方法已经满足我们日常大多数需求,比如get.filter.exclude.delete神马的感觉就已经无所不能了,但随着项目但业 ...
- windows库
1.windows库的存在方式 1.1.静态库:不能被加载的程序,可以理解为目标程序的归档:*.lib. 1.2.动态库:是可以被加载的程序:*.dll. 2.静态库 2.1.静态库的特点 目标 ...
- js 判断是ie浏览器
if (!+[1,]) { //IE window.event.returnValue = false; } else { return false; }
- IO多路复用客户端-服务器模型
IO多路复用服务器 -- 实现字符回射 服务器端 /************************************************************************* ...
- arm-linux工具
arm-linux工具的功能如下: arm-linux-addr2line 把程序地址转换为文件名和行号.在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上 ...
- Win10下配置Java 环境变量
在Win10中配置环境变量的方法跟在Win8和Win7中有些不同,看了看网上好多还是Win7/8里面的配置方法.虽然从原理上基本上没什么问题,但有些细节却会让人很苦恼.特意整理下新的配置方法.我假定你 ...