URAL 1521 War Games 2 树状数组解决约瑟夫环,输出离队顺序

1521. War Games 2

Time limit: 1.0 second

Memory limit: 64 MB

Background

During the latest war games (this story is fully described in the problem "War games") the Minister of Defense of the
Soviet Federation comrade Ivanov had a good chance to make sure personally, that an alertness of the Soviet Army under his command is just brilliant. But there was a thing, that continued to worry him. Being an outstanding commander, he realized, that only
physical conditions of the soldiers were demonstrated. So the time came to organize one more war games and examine their mental capacity.

General Rascal was appointed to be responsible for the war games again. The general donated the allocated funds to the poor and went to bed free-hearted. In his dream, the tactics manual appeared to
him and described a scheme, that allows to organize the war games absolutely free of charge.

Problem

In accordance with this scheme, the war games are divided into N phases; and N soldiers, successively numbered from 1 to N, are marching round a circle
one after another, i.e. the first follows the second, the second follows the third, ..., the (N-1)-th follows the N-th, and the N-th follows the first. At each phase, a single soldier leaves the circle and
goes to clean the WC, while the others continue to march. At some phase, the circle is left by a soldier, who is marching Kpositions before the one, who left the circle at the previous phase. A soldier, whose number is K,
leaves the circle at the first phase.

Surely, Mr. Rascal cherished no hope about his soldiers‘ abilities to determine an order of leaving the circle. "These fools can not even paint the grass properly", - he sniffed scornfully and went
to sergeant Filcher for an assistance.

Input

The only line contains the integer numbers N (1 ≤ N ≤ 100000) and K (1 ≤ K ≤ N).

Output

You should output the numbers of soldiers as they leave the circle. The numbers should be separated by single spaces.

Sample

input output
5 3
3 1 5 2 4

题意:约瑟夫环问题。  输入n是总人数,数到k的人离队。 输出离队顺序。

做法:因为要输出在原串中的位置,所以用了树状数组加二分来找。树状数组开始每个点都初始化为1,然后离队的改为减一。对于sum(x),x是原来环的 标号,sum(x) 就表示 当前 减少了人数的环中 对应的 是第几个。

//树状数组  单点更新  区间查询
#include <stdio.h>
#include <string.h>
const int MAX_N=100000+5;//开到区间大小就够了
int bit[MAX_N],N;  //

int sum(int i)
{
	int s=0;
	while(i>0)
	{
		s+=bit[i];
		i-=i&(-i);  //感觉从底层向上加。  加减二进制末尾的1
	}
	return s;
}

void add(int i,int x)
{
	while(i<=N)
	{
		bit[i]+=x;
		i+=i&(-i);
	}
}
int find(int x,int n)
{
	int l=1,r=n;
	while(l<=r)
	{
		int mid=(l+r)/2;
		int tem=sum(mid);
		if(tem<x)
			l=mid+1;
		else
			r=mid-1;
	}
	printf("%d ",l);
	return l;
}
int main()
{
	int n,k;
	scanf("%d%d",&n,&k);
	N=n;
	memset(bit,0,sizeof(bit));
	for(int i=1;i<=n;i++)
		add(i,1);
	int cur = 1;
	int res = n;
	for(int i=1;i<=n;i++)
	{
		cur=(cur+k-1)%res;
		if(cur==0)
			cur=res;
		int tem=find(cur,n);
		add(tem,-1);
		res--;
	}
	return 0;
}

时间: 2024-09-29 18:22:18

URAL 1521 War Games 2 树状数组解决约瑟夫环,输出离队顺序的相关文章

[扫描线+树状数组]解决矩形包含点的问题

今天做到第二题,大部分的思路都理解了之后最后剩下一个问题 zzx:“然后扫描线+树状数组搞一下就好了” 看到这两个算法就产生了一种我肯定会的错觉... 然后后来发现并不会的时候很惭愧... 然后十分感谢YDC,在之前完全陌生的情况下 我去问这样一个问题 超级超级超级耐心地给我解答  我问着每一个他们看起来显然的具体处理方法 突然发现真的像张老师说的:“你普及升提高的这条路没有怎么走,中间那块知识是空着的啊” 今天才切实体会到...但是或许正是这样今天学到这样的一个东西更让我觉得开心吧 树状数组解

URAL 2062 Ambitious Experiment(树状数组)

题目地址:http://acm.timus.ru/problem.aspx?space=1&num=2062 思路:对于x位置上的数,对其有贡献的数为位置为x的因数且属于修改区间[l,r]的数.所以对于查询操作ans=a[p]+sigma(sum(j)) (j为p的约数).区间修改时仅需修改区间端点值:c[l]+=d,c[r+1]-=d(当数x在某个无重复区间[l,r]时,每次求前x项的和时已包含该区间即已加上该数贡献,当x>r时,求前x项和时,该区间和为0,即数x贡献为0). #inclu

A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 69589   Accepted: 21437 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

【刷题小记】用数组模拟约瑟夫环

问题描述: n 个人围城一圈,第1个人从1开始报数,报数到m的人出列,然后从下一个人开始又从1开始报数,重复游戏n-1次,每次淘汰1人,最后剩下的人就是胜利者. 实心方法: 这是约瑟夫环问题,可以用链表实现,我在这里用数组实现,具体分析如下: 用到变量:以n=8,m=4为例说明 r:控制循环次数 i:用于记录每次出列的人位置,从1变化到8再到1 j:用于控制报数,从1变化到4,在到1.... 图1 图2 图3 图4 图5 图6 图7 图8 注意的地方: 1)模拟报数过程,从1开始报数,达到4后,

数组实现约瑟夫环

代码 #include<bits/stdc++.h> using namespace std; const int maxn=1000; int main(){ string name[maxn];//创建字符串数组保持参与人的名字 int p[maxn]; int n,i; cin>>n; for(i=0;i<n;i++) cin>>name[i]; int w,s;//w为开始的人的编号,s为数到第s个人,他出局 for(i=0;i<n;i++){ p[

POJ3928 Pingpong(统计比 K 小的个数 + 树状数组)

Ping pong Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2691   Accepted: 996 Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To im

【二维树状数组】See you~

https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/F [题意] 给定一个矩阵,每个格子的初始值为1.现在可以对矩阵有四种操作: A x y n1 :给格点(x,y)的值加n1 D x y n1: 给格点(x,y)的值减n1,如果现在格点的值不够n1,把格点置0 M x1 y1 x2 y2:(x1,y1)移动给(x2,y2)n1个 S x1 y1 x2 y2 查询子矩阵的和 [思路] 当然是二维树状数组 但是一定要注意:lowbi

soj 1088. Cows(树状数组)

可以用树状数组解决. 先按左端点递增排序,左端点相等的按右端点降序排列. 然后从左往有扫,更新答案同时更新sum数组. 对于一只Cow i,ans[i]为f(i)-g(i). f(i)为满足p[j].s<=p[i].s&&p[j].e>=p[i].e(0<=j<n,j!=i)的Cow只数. g(i)为满足p[j].s==p[i].s&&p[j].e==p[i].e(0<=j<n,j!=i)的Cow只数. 开个d数组维护一下,d[i]即为g

树状数组模板(改点求段 / 该段求点 / 改段求段)

1. 改点求段(单点更新, 区间求和) 代码: 1 #include <iostream> 2 using namespace std; 3 4 const int MAXN = 1e5 + 10; 5 int tree[MAXN], n; 6 7 int lowbit(int x){//返回 pow(2, k),其中k为末尾0的个数, 即返回最低位1的值 8 return x & -x; 9 } 10 11 void add(int x, int d){//将d累加到tree数组对应