zoukankan      html  css  js  c++  java
  • 【博弈论】【SG函数】【线段树】Petrozavodsk Summer Training Camp 2016 Day 9: AtCoder Japanese Problems Selection, Thursday, September 1, 2016 Problem H. Cups and Beans

    一开始有n个杯子,每个杯子里有一些豆子,两个人轮流操作,每次只能将一个豆子移动到其所在杯子之前的某个杯子里,不过可以移动到的范围只有一段区间。问你是否先手必胜。

    一个杯子里的豆子全都等价的,因为sg函数是异或起来的值,所以一个杯子里如果有偶数个豆子,就没有意义。

    用sg(i)表示i杯子中的豆子的sg值,sg(i)就是其所能移动到的那段杯子的区间的sg值的mex(未出现的最小非负整数)。可以用线段树去做。是经典问题。

    由于每次看似是后缀询问,实则是全局询问,故而主席树完全是多余的。

    回顾一下区间mex的求法:

    主席树里每个值的位置存当前该值出现的最右位置。

    如果root[r]的前缀主席树中,某值最右位置大于等于l,说明该值出现在了l,r中。

    所以主席树维护区间最小值,如果左半值域的最小值<l,则说明左半值域有值未在l,r出现,则查询左子树;否则查询右子树。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 100010
    struct Node{int v,lc,rc;}T[N*22];
    int root[N],e;
    void Insert(int pre,int cur,int p,int v,int l,int r)
    {
        if(l==r)
          {
            T[cur].v=v;
            return;
          }
        int m=(l+r>>1);
        if(p<=m)
          {
            T[cur].lc=++e;
            T[cur].rc=T[pre].rc;
            Insert(T[pre].lc,T[cur].lc,p,v,l,m);
          }
        else
          {
            T[cur].rc=++e;
            T[cur].lc=T[pre].lc;
            Insert(T[pre].rc,T[cur].rc,p,v,m+1,r);
          }
        T[cur].v=min(T[T[cur].lc].v,T[T[cur].rc].v);
    }
    int Goal;
    int Query(int R,int l,int r)
    {
        if(l==r) return l;
        int m=(l+r>>1);
        if(T[T[R].lc].v<Goal) return Query(T[R].lc,l,m);
        else return Query(T[R].rc,m+1,r);
    }
    int n,a[N],C[N],anss[N];
    int main()
    {
    //	freopen("h.in","r",stdin);
        int x,y;
        scanf("%d",&n);
        root[1]=++e;
        Insert(root[0],root[1],1,1,1,100001);
        for(int i=1;i<n;++i)
          {
            scanf("%d%d",&C[i],&a[i]);
            Goal=i+1-C[i];
            anss[i]=Query(root[i],1,100001)-1;
            root[i+1]=++e;
            Insert(root[i],root[i+1],anss[i]+1,i+1,1,100001);
          }
        int ans=0;
        for(int i=1;i<n;++i){
        	if(a[i]&1){
        		ans^=anss[i];
        	}
        }
        puts(ans ? "First" : "Second");
        return 0;
    }
  • 相关阅读:
    AtCoder Beginner Contest 184 ABCDE 题解
    Codeforces Round #685 (Div. 2) C. String Equality 思维
    Codeforces Round #682 (Div. 2) ABC 题解
    Gym 102215 & 队内训练#5
    【题解】 CF436E Cardboard Box 带悔贪心
    【题解】 「NOI2019」序列 模拟费用流 LOJ3158
    【笔记】 exlucas
    【题解】 「HNOI2018」毒瘤 树形dp+动态dp+容斥+格雷码 LOJ2496
    【笔记】 异或高斯消元方案数
    【笔记】 用生成函数推二项式反演
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7376692.html
Copyright © 2011-2022 走看看