codeforces255E Furlo and Rublo and Game SG函数

来源:互联网 发布:java 断点 编译后 存在 编辑:程序博客网 时间:2024/06/03 17:26
对SG函数的理解:

自认为sg函数应该算是博弈论中比较经典的东西了。。他几乎可以解决博弈论中的所有问题。你可以将sg函数看作是一个深搜的的过程。而每一堆的石子就相当于图中间的节点。所以说整个sg函数的过程就是在对一个有向无环图进行dfs的过程。

sg函数的具体内容可以用一个公式来表示(虽然我最不喜欢公式,不过我还是得写。不然这没法说清楚):sg(x) =mex{sg(y) : y ∈ F(x)}。其中{}内的是一个集合(只要上过高中都应该知道吧),在:右边的是该集合元素所满足的条件。sg(y)为该元素的值(其实就是一个递归的过程)。重点来了。。mex()函数表示是不在该集合中的最小的非负整数的值。比如mex({1,2,3})=0...mex({0,2,4})=1...mex({})=0..最后得出来的结果中。为0为必败点,不为零必胜点。。F(x)是x能达到的节点。

接下来才是sg函数精妙之处了。假如说是在一个游戏中有多个石子堆该怎么办了。我们只需要把对每个石子堆进行sg函数的调用,将得到的所有的值进行异或。得出来的结果为0则该情形为必败态。否则为必胜态。。


此题求出1e6以内的sg值,超出的另外求。排序,尺取法。

import java.io.*;import java.util.ArrayList;import java.util.Arrays;import java.util.Scanner;import java.util.StringTokenizer;public class Main {public static void main(String[] args) {InputStream inputStream = System.in;          OutputStream outputStream = System.out;          InputReader in = new InputReader(inputStream);          PrintWriter out = new PrintWriter(outputStream);          new Task().solve(in, out);          out.close();  }}class Task {          static final long mod=1000000007;      static final int maxn=1000005;      public void solve(InputReader in,PrintWriter out) {int sg[]=new int[maxn];int ws[]=new int[maxn];sg[0]=0; Arrays.fill(ws, 0);int a=0,b=0;for(int i=1;i<=1000000;i++) {while(a*a<=i&&a<i) {ws[sg[a]]++;a++;}while(b*b*b*b<i) {ws[sg[b]]--;b++;}sg[i]=0;while(ws[sg[i]]!=0) {sg[i]++;}}int n=in.nextInt();long d[]=new long[n];for(int i=0;i<n;i++)d[i]=in.nextLong();Arrays.sort(d);int ans=0;Arrays.fill(ws,0);a=0; b=0;for(int i=0;i<n;i++) {long c=d[i];if(c<=1000000)ans^=sg[(int)c];else {while((long)a*a<=c&&a<c) {ws[sg[a]]++;a++;}while((long)b*b*b*b<c) {ws[sg[b]]--;b++;}int u=0;while(ws[u]!=0) {u++;}ans^=u;}}if(ans==0)out.println("Rublo");elseout.println("Furlo");    }class Pair implements Comparable<Pair>{public int compareTo(Pair arg0) {return 0;}    }  } class InputReader {      public BufferedReader reader;      public StringTokenizer tokenizer;        public InputReader(InputStream stream) {          reader = new BufferedReader(new InputStreamReader(stream), 32768);          tokenizer = null;      }        public String next() {          while (tokenizer == null || !tokenizer.hasMoreTokens()) {              try {                  tokenizer = new StringTokenizer(reader.readLine());              } catch (IOException e) {                  throw new RuntimeException(e);              }          }          return tokenizer.nextToken();      }        public int nextInt() {          return Integer.parseInt(next());      }            public long nextLong() {          return Long.parseLong(next());      }            public double nextDouble() {          return Double.parseDouble(next());      }            public boolean hasNext() {          return  new Scanner(System.in).hasNext();      }  }


0 0
原创粉丝点击