• BZOJ.4513.[SDOI2016]储能表(数位DP)


    BZOJ
    洛谷

    切了一道简单的数位DP,终于有些没白做题的感觉了...(然而mjt更强没做过这类的题也切了orz)


    看部分分,如果(k=0),就是求(sum_{i=0}^nsum_{j=0}^mi mathbb{xor} j)。这个数据范围考虑数位DP。(其实统计一下(leq n)(leq m)中每位为(1)的数有多少个就行了...)
    如果你做过字节跳动冬令营网络赛 D.The Easiest One(没做过也行),就可以想到枚举每一位的时候,同时枚举(x,y)这一位选啥,处理一下贡献就行了。
    对于(k)的限制,同样对(k)二进制分解,转移时判一下如果当前(<k)continue就行了...

    看代码很好理解...

    貌似有很神的代码...见洛谷rank1=-=


    //828kb	1532ms
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define mp std::make_pair
    #define pr std::pair<int,int>
    #define gc() getchar()
    typedef long long LL;
    const int N=66,INF=1e9+7;
    
    int P,bitx[N],bity[N],bitk[N];
    LL pw[N];
    pr f[N][8];
    bool vis[N][8];
    
    inline LL read()
    {
    	LL now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-48,c=gc());
    	return now;
    }
    pr DFS(int x,int s)//pair(和,方案数)
    {//0:==k 1:>k
    	if(x==-1) return mp(0,1);
    	if(vis[x][s]) return f[x][s];
    	int upx=s&1?bitx[x]:1, upy=s&2?bity[x]:1, sk=s&4;
    	LL f1=0,f2=0;
    	for(int i=0; i<=upx; ++i)
    		for(int j=0; j<=upy; ++j)
    		{
    			int val=(i^j)-bitk[x];
    			if(!sk && val<0) continue;
    			pr v=DFS(x-1,(s&1&&i==upx)|((s&2&&j==upy)<<1)|((sk||val>0)<<2));
    			if(val) f1+=val*pw[x]*v.second%P;
    			f1+=v.first, f2+=v.second;
    		}
    	return vis[x][s]=1,f[x][s]=mp((f1%P+P)%P,f2%P);
    }
    void Calc(LL x,LL y,LL k)
    {
    	memset(vis,0,sizeof vis);
    	memset(bitx,0,sizeof bitx);
    	memset(bity,0,sizeof bity);
    	memset(bitk,0,sizeof bitk);
    	int t1=0,t2=0,t3=0;
    	for(; x; x>>=1) bitx[t1++]=x&1;
    	for(; y; y>>=1) bity[t2++]=y&1;
    	for(; k; k>>=1) bitk[t3++]=k&1;
    	printf("%d
    ",DFS(std::max(t1,std::max(t2,t3))-1,3).first);
    }
    
    int main()
    {
    	freopen("table.in","r",stdin);
    	freopen("table.out","w",stdout);
    
    	for(int T=read(); T--; )
    	{
    		LL n=read()-1,m=read()-1,K=read(); int P=read(); ::P=P;
    		for(int i=0; i<63; ++i) pw[i]=(1ll<<i)%P;
    		Calc(n,m,K);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    二.线性表
    一.绪论
    托管服务器代码
    jquery easyui DataGrid 数据表格 属性
    用socket 模拟http请求
    struct和class的相同点与不同点
    c++中的基本数据类型
    当函数返回一个局部变量的指针问题,内存是否被释放
    Python首先生成包含1000个随机字符的字符串,然后统计每个字符的出现次数。(使用字典)
    浅谈结构体字节的求法
  • 原文地址:https://www.cnblogs.com/SovietPower/p/10392446.html
Copyright © 2020-2023  润新知