题目大意:
有一个由
1→n
顺时针构成的环,从点
1
开始走,算自己每次走
分析:
中心思想模拟,考虑到我们删掉一些点后会走大量无效状态,我们可以设定每删除若干个点,重新构环,这样可以大幅度加速模拟。同时尽量少用取模,
AC code:
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#define pb push_back
#define mp make_pair
#define debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef double DB;
typedef long double LD;
using namespace std;
const int MAXN = 2000009;
int n, q;
int num[MAXN], tot;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; ++i)
num[i] = i;
int tmp, tmptot, d = 1;
int block = n/10, now = 1;
if(!block) block = n;
tot = n;
for(int i = 1; i < n; ++i)
{
if(i%block == 0)
{
tmptot = 0, tmp = num[now];
for(int j = 1; j <= tot; ++j)
if(num[j])
{
num[++tmptot] = num[j];
if(num[j] == tmp) now = tmptot;
}
tot = tmptot;
}
for(int j = 1; j < q; ++j)
{
do
{
now += d;
if(now > tot) now -= tot;
else if(now < 1) now += tot;
}while(!num[now]);
}
num[now] = 0;
do
{
now++;
if(now > tot) now -= tot;
}while(!num[now]);
if(num[now]&1) d = 1;
else d = -1;
}
printf("%d\n", num[now]);
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}