//============================================================================
// Name        : 博弈_序列中子序列异或值大于0.cpp
// Author      : cchun
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
/*
 * state: Accepted    2060 KB    490 ms    C++ (g++ 4.4.5)
 * 题目大意:
 *         给定一段序列,序列要用代码生成(这个纯粹是没有用的,不过有时候可能转机在这些东西也不一定)。然后
 *         要求在这段序列上选择一个连续子序列,然后要求这个子序列Nim游戏,先手可胜利。
 * 解题思路:
 *         把序列生成,然后序列变为a[i]^a[i+1]^a[i+2]^………^a[j] = dp[j]^dp[i-1], dp[i]为(a[0]^a[1]^a[2]^……^a[i]).
 *         然后就可以变为计数问题了。
 *         如果序列为3,那么所有的序列的异或值为:
 *         dp[0], dp[1], dp[2]
 *         dp[1]^dp[0], dp[2]^dp[0]
 *         dp[2]^dp[1]
 *         总共为3+2+1, 就是n*(n+1)/2种。排除其中为0的就行了。
 *         就可以变为弄一个循环,然后再hash统计下后面有多少个跟它相同的。相同的就是不行,统计全部后用总值减去,就是解。
 * 注意事项:
 *         那一步hash比赛时我为了求快用map,结果TLE了,比赛结束用hash表就ac了,490ms,花了1/5的时间。
 *         理论时间复杂度,接近O(n),因为hash不是稳定的。比网络上那些需要排序的算法理论上快一些,因为
 *         涉及到排序的算法,时间复杂度的下界为O(n*log(n))
 */
View Code
  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <algorithm>
  4 #include <functional>
  5 #include <cmath>
  6 #include <cstring>
  7 #include <string>
  8 #include <vector>
  9 #include <map>
 10 #include <set>
 11 #include <utility>
 12 #include <stack>
 13 #include <queue>
 14 #include <deque>
 15 #include <bitset>
 16 #include <iomanip>
 17 #include <sstream>
 18 
 19 #define abs(x) ((x)>0?(x):-(x))
 20 #define sqr(x) ((x)*(x))
 21 
 22 #define all(x) x.begin(), x.end()
 23 #define rall(v) v.rbegin(),v.rend()
 24 
 25 #define ll long long
 26 #define ull unsigned long long
 27 
 28 #define FOR(i,a,b)        for(int i=(a); i<(b);i++)
 29 #define FF(i,a)            for(int i=0; i<(a);i++)
 30 #define FFD(i,a)        for(int i=(a)-1; i>=0;i--)
 31 #define CC(m,what)        memset(m,what,sizeof(m))
 32 #define SZ(a)            ((int)a.size())
 33 #define viewPP(a,n,m)    {puts("---");FF(i,n){FF(j,m) cout<<a[i][j] <<' ';puts("");}}
 34 #define viewP(a, n)     {FF(i, n) {cout<<a[i]<<" ";} puts("");}
 35 
 36 #define read            freopen("in.txt","r",stdin)
 37 #define write            freopen("out.txt","w",stdout)
 38 
 39 const double eps = 1e-11;
 40 const int inf = 0x7fffffff;
 41 const int hinf = 0x3f3f3f3f;
 42 const double pi = 3.1415926535897932;
 43 
 44 int dx[] = {-1, 0, 1, 0};//up Right down Left
 45 int dy[] = {0,  1, 0, -1};
 46 
 47 using namespace std;
 48 const int maxn = 100005;
 49 int S, W, N;
 50 int a[maxn];
 51 int dp[maxn];
 52 
 53 
 54 class myHash {
 55 public:
 56     static const int MAXN = 139991;
 57     static const int hinf = 0x3f3f3f3f;
 58     int Hash[MAXN];
 59     int hashVal[MAXN];
 60     int k;
 61     bool get_key(int x, int &ind) {
 62         int k = ((x % MAXN) + MAXN) % MAXN;
 63         for(int i = 1; Hash[k] != -hinf; i *= i) {
 64             if(Hash[k] == x) {
 65                 ind = k;
 66                 return true;
 67             }
 68             k += i;
 69             k %= MAXN;
 70         }
 71         ind = k;
 72         return false;
 73     }
 74     void init() {
 75         FF(i, MAXN)
 76             Hash[i] = -hinf;
 77         memset(hashVal, 0, sizeof(hashVal));
 78     }
 79 };
 80 myHash H;
 81 
 82 void create() {
 83     int g = S;
 84     for (int i=0; i<N; i++) {
 85         a[i] = g;
 86         if( a[i] == 0 ) { a[i] = g = W; }
 87         if( g%2 == 0 ) { g = (g/2); }
 88         else           { g = (g/2) ^ W; }
 89     }
 90     //viewP(a, N);
 91     ll t = N;
 92     ll sol = (t+1)*t / 2;
 93     ll canot = 0;
 94     dp[0] = a[0];
 95     if(!dp[0])
 96         canot++;
 97     FOR(i, 1, N) {
 98         dp[i] = dp[i-1] ^ a[i];
 99         if(!dp[i])
100             canot++;
101     }
102 
103     H.init();
104     for(int i = 0; i < N; i++) {
105         H.get_key(dp[i], H.k);
106         H.Hash[H.k] = dp[i];
107         H.hashVal[H.k]++;
108     }
109     for(int i = 0; i < N-1; i++) {
110         if(H.get_key(dp[i], H.k)) {
111             if(H.hashVal[H.k] >= 1)
112                 H.hashVal[H.k]--;
113         }
114         canot += H.hashVal[H.k];
115     }
116     printf("%lld\n", sol - canot);
117 }
118 
119 int main()
120 {
121 #ifndef ONLINE_JUDGE
122     //freopen("in.txt", "r", stdin);
123 #endif
124     int cas;
125     scanf("%d", &cas);
126     while(cas--) {
127         scanf("%d%d%d", &N, &S, &W);
128         create();
129     }
130     return 0;
131 }

 

posted on 2013-05-08 11:05  cchun  阅读(664)  评论(0编辑  收藏  举报