ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解 CF494E 【Sharti】

2020-09-24 19:32:15  阅读:160  来源: 互联网

标签:frac CF494E Sharti read 题解 text SG lowbit cur


发现本题为公平组合游戏,考虑用 \(\text{SG}\) 函数来解决。

对于翻硬币游戏,一个状态的 \(\text{SG}\) 值为当前状态的每个正面朝上的硬币单一存在时的 \(\text{SG}\) 值的异或和。

可以用归纳法得到位置 \((x,y)\) 的 \(\text{SG}\) 值:

\[\large\text{SG}(x,y)=\min\{\text{lowbit}(x),\text{lowbit}(y) ,\text{greatbit}(k)\} \]

那么每个位置的 \(\text{SG}\) 值都是 \(2^t\) 的形式。

考虑如何计算区间 \([l,r]\) 的 \(\text{lowbit}\) 的异或和,得 \(i\) 作为 \(\text{lowbit}\) 的贡献次数为:

\[\large\frac{r}{i}-\frac{l-1}{i}-\left(\frac{r}{2i}-\frac{l-1}{2i}\right) \]

前一项为所有情况,后一项为 \(i\) 不为 \(\text{lowbit}\) 的情况。

可以用扫描线来分别统计行和列的答案,然后再合并。直接算 \(\text{SG}\) 值等于 \(2^t\) 的个数不好算,可以算出 \(\geqslant2^t\) 的个数,等于 \(2^t\) 的个数作差即可求得。

#include<bits/stdc++.h>
#define maxn 100010
#define maxm 3000010
#define mid ((l+r)>>1)
using namespace std;
template<typename T> inline void read(T &x)
{
    x=0;char c=getchar();bool flag=false;
    while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    if(flag)x=-x;
}
int n,m,k,lim=1,t,ans,root,tot,cnt;
int num[maxn],ls[maxm],rs[maxm],tag[maxm],sum[maxm],val[maxm];
struct node
{
    int x,l,r,v;
}p[maxn];
bool cmp(const node &a,const node &b)
{
    return a.x<b.x;
}
int get(int l,int r)
{
    int v=0;
    for(int i=1;i<=k;i<<=1)
        v|=(((r/i-(l-1)/i)-(i*2<=k?r/i/2-(l-1)/i/2:0))&1)*i;
    return v;
}
void pushup(int cur,int l,int r)
{
    if(tag[cur]) sum[cur]=val[cur];
    else sum[cur]=sum[ls[cur]]^sum[rs[cur]];
}
void modify(int L,int R,int l,int r,int v,int &cur)
{
    if(!cur) cur=++tot;
    val[cur]=get(l,r);
    if(L<=l&&R>=r)
    {
        tag[cur]+=v,pushup(cur,l,r);
        return;
    }
    if(L<=mid) modify(L,R,l,mid,v,ls[cur]);
    if(R>mid) modify(L,R,mid+1,r,v,rs[cur]);
    pushup(cur,l,r);
}
int main()
{
    read(n),read(m),read(k);
    while(lim<=k) lim<<=1,t++;
    for(int i=1;i<=m;++i)
    {
        int u,d,l,r;
        read(l),read(u),read(r),read(d);
        p[++cnt]={l,u,d,1},p[++cnt]={r+1,u,d,-1};
    }
    sort(p+1,p+cnt+1,cmp);
    for(int i=1;i<=cnt;++i)
    {
        if(p[i-1].x!=p[i].x)
        {
            int v1=sum[root],v2=get(p[i-1].x,p[i].x-1),s1=0,s2=0;
            for(int j=lim,l=t;j;j>>=1,l--)
                s1+=((v1&j)!=0),s2+=((v2&j)!=0),num[l]+=s1*s2;
        }
        modify(p[i].l,p[i].r,1,n,p[i].v,root);
    }
    for(int i=0,j=1;i<t;++i,j<<=1)
        if((num[i]-num[i+1])&1)
            ans^=j;
    if(ans) puts("Hamed");
    else puts("Malek");
    return 0;
}

标签:frac,CF494E,Sharti,read,题解,text,SG,lowbit,cur
来源: https://www.cnblogs.com/lhm-/p/13726060.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有