zoukankan      html  css  js  c++  java
  • 【ZOJ3899】State Reversing 解题报告

    【ZOJ3899】State Reversing

    Description

    (N)不同的怪兽,编号从(1)(N)。Yukari有(M)相同的房间,编号为(1)(M)。每个房间是无限大的,每个房间有两种状态:可以住或者不可以住(一开始所有的房间都可以住)。Yukari每天都会选定一个区间 ([l,r]),把编号在这个区间的房间状态反转(可以住改成不可以住,不可以住改成可以住)。怪兽只能住在“可以住”的房间。每间“可以住”的房间至少有一个怪兽。

    Yukari想知道,每次反转后,有多少种方法为这些怪兽分配房间。两种方法(方法(A)和方法(B))认为是同种方法当且仅当对于方案(A)中任意一个房间(x),在方案(B)中存在一个房间(y)使得房间(x)和房间(y)住的怪兽的编号集合是一样的。换句话说,房间是相同的。

    Input

    第一行一个整数 (T(T≤5)) ,表示数据组数。

    接下来三个整数 (N,M,Q(1≤M≤N≤10^5,Q≤10^5)) ,分别表示怪兽数、房间数、操作次数。

    接下来(Q)行,每行两个整数 (l,r(1≤l≤r≤M)) ,表示Yukari会反转区间 ([l,r]) 的状态。

    方案数对(880803841)取模

    Output

    对于每次操作,输出进行反转操作后为怪兽分配房间的方案数。


    (n)个有标号的球求放到(m)个无标号的非空盒子里,发现就是第二类斯特林数,因为(m)会变,所以等价于求斯特林行。

    先考虑求出(n)个有标号的球出放到(m)个有标号的非空盒子里,即为({n race m}m!)

    [f_i={n race i}i! ]

    考虑进行容斥,设(g_i)代表(n)个有标号的球放到(i)个有标号的盒子里的方案数,则有

    [g_i=i^n ]

    显然有

    [g_k=sum_{i=0}^kinom{k}{i}f_i ]

    二项式反演

    [egin{aligned} f_k&=sum_{i=0}^k(-1)^iinom{k}{i}g_{k-i}\ &=sum_{i=0}^k(-1)^ifrac{k!}{(k-i)!i!}(k-i)^n\ &=k!sum_{i=0}^kfrac{(-1)^i}{i!}frac{(k-i)^n}{(k-i)!} end{aligned} ]

    所以

    [{nrace k}=sum_{i=0}^kfrac{(-1)^i}{i!}frac{(k-i)^n}{(k-i)!} ]

    然后卷一下子就行了,维护用个线段树就好


    Code:

    #include <cstdio>
    #include <algorithm>
    const int mod=880803841,G=26,Gi=711418487;
    const int N=1e5+10;
    #define add(a,b) ((a+b)%mod)
    #define mul(a,b) (1ll*(a)*(b)%mod)
    int qp(int d,int k){int f=1;while(k){if(k&1)f=mul(f,d);d=mul(d,d),k>>=1;}return f;}
    int n,m,q,a[N<<3],b[N<<3],turn[N<<3],fac[N<<3],len,L;
    void NTT(int *a,int typ)
    {
        for(int i=1;i<len;i++) if(i<turn[i]) std::swap(a[i],a[turn[i]]);
        for(int le=1;le<len;le<<=1)
        {
            int wn=qp(typ?G:Gi,(mod-1)/(le<<1));
            for(int p=0;p<len;p+=le<<1)
            {
                int w=1;
                for(int i=p;i<p+le;i++,w=mul(w,wn))
                {
                    int tx=a[i],ty=mul(w,a[i+le]);
                    a[i]=add(tx,ty);
                    a[i+le]=add(tx,mod-ty);
                }
            }
        }
        if(!typ)
        {
            int inv=qp(len,mod-2);
            for(int i=0;i<len;i++) a[i]=mul(a[i],inv);
        }
    }
    int sum[N<<2],tag[N<<2];
    #define ls id<<1
    #define rs id<<1|1
    void build(int id,int l,int r)
    {
        tag[id]=0,sum[id]=r+1-l;
        if(l==r) return;
        int mid=l+r>>1;
        build(ls,l,mid),build(rs,mid+1,r);
    }
    void pushdown(int id,int l,int r)
    {
        if(tag[id])
        {
            int mid=l+r>>1;
            sum[ls]=mid+1-l-sum[ls];
            sum[rs]=r-mid-sum[rs];
            tag[ls]^=1,tag[rs]^=1,tag[id]^=1;
        }
    }
    void change(int id,int L,int R,int l,int r)
    {
        if(L==l&&R==r)
        {
            sum[id]=R+1-L-sum[id];
            tag[id]^=1;
            return;
        }
        pushdown(id,L,R);
        int Mid=L+R>>1;
        if(r<=Mid) change(ls,L,Mid,l,r);
        else if(l>Mid) change(rs,Mid+1,R,l,r);
        else change(ls,L,Mid,l,Mid),change(rs,Mid+1,R,Mid+1,r);
        sum[id]=sum[ls]+sum[rs];
    }
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&m,&n,&q);
            len=1,L=-1;
            while(len<=m<<1) len<<=1,++L;
            for(int i=0;i<len;i++) a[i]=b[i]=0,turn[i]=turn[i>>1]>>1|(i&1)<<L;
            fac[0]=1;for(int i=1;i<=m;i++) fac[i]=mul(fac[i-1],i);
            a[m]=b[m]=qp(fac[m],mod-2);
            for(int i=m-1;~i;i--) b[i]=a[i]=mul(a[i+1],i+1);
            for(int i=1;i<=m;i+=2) a[i]=mod-a[i];
            for(int i=0;i<=m;i++) b[i]=mul(b[i],qp(i,m));
            NTT(a,1),NTT(b,1);
            for(int i=0;i<len;i++) a[i]=mul(a[i],b[i]);
            NTT(a,0);
            build(1,1,n);
            for(int l,r,i=1;i<=q;i++)
            {
                scanf("%d%d",&l,&r);
                change(1,1,n,l,r);
                printf("%d
    ",a[sum[1]]);
            }
        }
        return 0;
    }
    

    2018.12.22

  • 相关阅读:
    SQLServer存储过程实现单条件分页
    AJAX遮罩实例
    JS获取网站StatusCode,若存在写入文件
    AJAX同步和异步的区别
    通过JS将BSAE64生成图片并下载
    Bootstrap学习-排版-表单
    Bootstrap学习-环境安装
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10161212.html
Copyright © 2011-2022 走看看