ZOJ 3591 Nim (连续子序列异或和)

题目链接:ZOJ 3591 Nim

题意:根据题目给出的代码得到n堆石头的各自的数量,求先手选出连续的若干堆并且必胜的方法数。(比如:3,1,1 每堆石头数是1,1,1.先手选出(1),(1),(1),(1,1,1) 这四种方案是必胜的,所以答案是4)

思路:在n堆取石头首先想到的是Nim博弈,连续的若干堆,即求连续子序列异或和为0的数量m,n*(n+1)/2-m就是答案

(Nim博弈结论,a1,a2,a3……an,an-1,若a1^a2^a3^……^an^an-1=0先手必败 )

连续子序列异或和类似连续子序列和 详细请看:http://blog.csdn.net/u012377575/article/details/44906065

如有不妥之处,欢迎指正!

AC代码:

#include <stdio.h>
#include <map>
#include <algorithm>
#include <string.h>
#define LL long long
using namespace std;
LL a[100010];
LL sumXor[100010];
map<LL,LL> vis;
void getA(LL n,LL w,LL s){
    LL i;
    LL g=s;
    for(i=0;i<n;i++){
        a[i]=g;
        if(a[i]==0){
            a[i]=g=w;
        }
        if(g%2==0) g=g/2;
        else g=(g/2)^w;
    }
}

int main()
{
    int t,i;
    LL n,w,s;
    scanf("%d",&t);
    while(t--){
        vis.clear();
        memset(sumXor,0,sizeof sumXor);
        scanf("%lld %lld %lld",&n,&s,&w);
        getA(n,w,s);
        LL ans=0;
        sumXor[0]=a[0];
        for(i=1;i<n;i++)
            sumXor[i]=sumXor[i-1]^a[i];
        LL u;
        vis[0]=1;
        for(i=0;i<n;i++){
            u=sumXor[i];
            ans+=vis[u];
            vis[u]++;
        }
        printf("%lld\n",n*(n+1)/2-ans);
    }
    return 0;
}
时间: 2024-08-05 22:51:54

ZOJ 3591 Nim (连续子序列异或和)的相关文章

ZOJ 3591 Nim 前缀和+位运算

Nim Time Limit: 3 Seconds      Memory Limit: 65536 KB Nim is a mathematical game of strategy in which two players take turns removing objects from distinct heaps. The game ends when one of the players is unable to remove object in his/her turn. This

zoj 3591 Nim

Nim Time Limit: 3 Seconds      Memory Limit: 65536 KB Nim is a mathematical game of strategy in which two players take turns removing objects from distinct heaps. The game ends when one of the players is unable to remove object in his/her turn. This

Zoj 3591 Nim 【博弈】【搜索】

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3591 题目大意:给你T组case,每组case有N,S,W三个数字,根据题目给出的代码可以算出每组石子个数a[i]. 已知了N组石子的个数,现在让你来选出连续的石子堆,使得先手会赢,问有多少种选法. 比如给出的样例:NSW分别是 3 1 1 则算出来的每堆石子的个数a[i]是 1 1 1,则 1 1 1三堆石子的选法有: 选第一堆,选第二堆,选第三堆,选第一堆到

ZOJ 3872 Beauty of Array 连续子序列求和

Edward has an array A with N integers. He defines the beauty of an array as the summation of all distinct integers in the array. Now Edward wants to know the summation of the beauty of all contiguous subarray of the array A. Input There are multiple

最大连续子序列和

对于给定的数组 numnum,一个长度为 ss 的连续子序列是指由 num_i,num_{i+1},num_{i+2}\ldots,num_{i+s-1}num?i??,num?i+1??,num?i+2??…,num?i+s−1?? 组成的序列.数组中的元素有可能为正数.负数或 00.你需要从数组中找出元素总和最大的一个连续子序列. 比如,对于数组 1,-3,2,6,-5,81,−3,2,6,−5,8,其最大连续子序列之和是 2+6-5+8=112+6−5+8=11. 对于一段区间内的最大连续

hdu1231 最大连续子序列

最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 22849    Accepted Submission(s): 10135 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j

dp-最大连续子序列的和

什么是最大连续子序列和呢 ? 最大连续子序列和是所有子序列中元素和最大的一个 . 问题 : 给定一个序列 { -2, 11, -4, 13, -5, -2 } , 则最大连续子序列和为 20 , 即 { 11 , -4 , 13 } . 分析 : 要怎样去解决这个问题呢 ? 设出 两个变量 , 一个 ans 用来存放最终的结果 , 一个用来现在对元素进行加和 , 每当有最大的和则更形下 ans . 代码示例 : #include <iostream> #include <cstring&

HDU1231 最长连续子序列

最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 31687    Accepted Submission(s): 14214 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j

动态规划:最大连续子序列和

问题:给出一个数组,求其连续子序列的最大和 package 动态规划; /** * 给出一个数组,求其连续子数组的最大和 * @author Administrator * */ public class MaxSum { public static void main(String[] args) { int[] arr = new int[]{-3,1,-3,4,-1,2,1}; int max=arr[0]; int current=arr[0]; for(int i=1;i<arr.le