zoukankan      html  css  js  c++  java
  • CF1033G Chip Game 题解

    Luogu
    Codeforces

    Description.

    \(n\) 堆石子,Alice Bob 打隔膜,他们分别从 \([1,m]\) 中选一个值,设为 \(A\)\(B\)
    Alice Bob 分别可以从任意一堆中取出 \(A\)\(B\) 个石子,不能操作的人输。
    问对于不同的 \(A,B\),以下四种状态的方案数分别是多少。

    1. Alice 赢
    2. Bob 赢
    3. 先手赢
    4. 后手赢

    \(n\le 100,m\le 10^5\)

    Solution.

    首先,发现 Alice 赢和 Bob 赢本质相同,方案数相同。
    所以我们只需要算出先手赢、后手赢的方案数容斥就行了。

    同时,显然的性质就是状态 \(\{v_i\}\) 和状态 \(\{v_i+k_i(a+b)\}\) 等价。
    证明显然,赢的人肯定可以按照原来状态,如果后手选了就跟他把 \(k_i\) 减一。

    那我们可以考虑枚举 \(a+b\),剩下了所有的 \(v_i\le (a+b)\)
    考虑先手赢,可能会有这几种情况

    1. \(\exists i\in[1,n],a\le v_i< b\),是因为先手可以苟着 \(v_i\) 最后取。
    2. \(\exists i\in[1,n],2a\le v_i\),有 \(2a\le v_i\le a+b\),先手可以先取一个 \(a\) 再苟。

    先手能苟的情况也就只有这两种。
    考虑不能苟,那也就是说 \(\sum[v_i\ge b]\) 是偶数。
    所以先手必败的情况是没有情况 1 和 2 且是偶数。
    同理,后手赢的情况有以下几种

    1. \(\exists i\in[1,n],b\le v_i< a\)
    2. \(\sum[2b\le v_i]\ge 2\)

    考虑 \(\forall i\in[1,n],a\le v_i<b\) 不成立,则肯定有 \(a,b\) 在同一个 \((v_i,v_{i+1}]\) 值域区间内。
    所以我们可以枚举这个值域区间,复杂度 \(O(n)\),可以 \(O(1)\) 算出 \(\sum[v_i\ge b]\)
    考虑 \(2a\le v_i\) 也不成立,所以肯定有 \(a>\frac {v_i}2\),直接找到最大的 \(v_i\) 就行了。
    后手的话考虑次大就行了。

    Coding.

    点击查看代码
    //Coded by leapfrog {{{
    //Coded on 2021.10.26
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    int n,m,b[105];ll a[105],rfs,rsc;
    int main()
    {
    	read(n,m);for(int i=1;i<=n;i++) read(a[i]);
    	for(int S=2;S<=m+m;S++)
    	{
    		for(int i=1;i<=n;i++) b[i]=a[i]%S;
    		b[n+1]=0,b[n+2]=S-1,sort(b+1,b+n+3);
    		for(int i=n+2;i>1;i--)
    		{
    			int fg=(n+2-i)&1,l=max(b[i-1],b[n+!fg]/2)+1,r=min(b[i],m);
    			(fg?rfs:rsc)+=max(min(r,S-l)-max(l,S-r)+1,0);
    		}
    	}
    	ll rs=(1ll*m*m-rfs-rsc)>>1;
    	return printf("%lld %lld %lld %lld\n",rs,rs,rfs,rsc),0;
    }
    
  • 相关阅读:
    机器学习笔记(二)---- 线性回归
    机器学习笔记(一)----基本概念
    ZZ:SDNLAB技术分享(一):ODL的SFC入门和Demo
    zz:NETCONF协议详解
    技术谈 | SDN 和 NFV 之间的爱与恨
    华为云内容审核—性能更加狂野,价格更加腼腆
    【并发技术01】传统线程技术中创建线程的两种方式
    【开发者portal在线开发插件系列五】命令的响应,即命令结果的上报(mid的使用)
    【并发技术16】线程同步工具Exchanger的使用
    什么是API文档?--斯科特·马文
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15467761.html
Copyright © 2011-2022 走看看