zoukankan      html  css  js  c++  java
  • 博弈_ZOJ3591_序列中子序列异或值大于0.cpp

    //============================================================================
    // 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 }
  • 相关阅读:
    MyCat简介+Mybatis实现多租户(链接)
    mybatis的sql执行过程底层源码分析和缓存原理分析
    推荐算法数据集
    CentOS系统初始化
    NAT
    VRRP
    BGP协议的原理及应用
    ospf协议的重分发
    静态路由的原理与配置、动态路由
    OSPF (企业内部使用的动态路由协议)
  • 原文地址:https://www.cnblogs.com/cchun/p/3066361.html
Copyright © 2011-2022 走看看