Atcoder arc091F

63 篇文章 0 订阅
2 篇文章 0 订阅

显然是算SG函数。
打个表出来,会发现 S G ( n , k ) SG(n,k) SG(n,k) n   m o d   k = 0 n\bmod k=0 nmodk=0时为 n / k n/k n/k,不过其他情况下似乎不能直接 O ( 1 ) \mathcal O(1) O(1)得出。
仔细分析一波,容易归纳证明 S G ( n − ⌊ n k ⌋ , k ) SG(n- \lfloor \frac{n}{k} \rfloor,k) SG(nkn,k) S G ( n , k ) SG(n,k) SG(n,k)互不相同且取遍 0 0 0~ ⌊ n k ⌋ \lfloor \frac{n}{k} \rfloor kn之间整数。于是当 n   m o d   k ≠ 0 n \bmod k \neq 0 nmodk=0时有 S G ( n , k ) = S G ( n − ⌊ n k ⌋ − 1 , k ) SG(n,k)=SG(n-\lfloor \frac{n}{k} \rfloor-1,k) SG(n,k)=SG(nkn1,k)。这样精细实现一下容易做到 O ( min ⁡ ( k log ⁡ n , ⌊ n k ⌋ ) ) \mathcal O(\min(k\log n,\lfloor \frac{n}{k} \rfloor)) O(min(klogn,kn))计算 S G ( n , k ) SG(n,k) SG(n,k)
时间复杂度 O ( N V log ⁡ V ) \mathcal O(N\sqrt {V\log V}) O(NVlogV )

#include <bits/stdc++.h>

using namespace std;

int calc(int n,int k) {
  while (n%k!=0) {
  	int t=n/k;
  	n-=(n-t*k+t)/(t+1)*(t+1);
  }
  return n/k;
}

int main() {
  int n;
  scanf("%d",&n);
  int s=0;
  for(int i=1;i<=n;i++) {
  	int x,y;
  	scanf("%d%d",&x,&y);
  	s^=calc(x,y);
  }
  puts((s)?"Takahashi":"Aoki");
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值