• 【CF809C】Find a car(动态规划)


    【CF809C】Find a car(动态规划)

    题面

    洛谷
    CF
    有一个无穷大的矩阵,第(i)行第(j)列的数是((i-1)xor(j-1)+1)(q)次询问,每次询问一个矩形内数小于等于(k)的数的和。

    题解

    询问等价于(sum_{i=l}^rsum_{j=L}^R [ioplus jle k]ioplus j)
    把询问拆分成四个从(1)开始的东西,即([1..r,1..R],[1..l-1,1..R],[1..r,1..L-1],[1..l-1,1..L-1])
    那么就可以大力数位(dp)了,设(f[i][0/1][0/1][0/1])表示(i)是否卡在界上,(j)是否卡在界上,(ioplus j)是否卡在界上,需要同时记录方案数和和。
    大力转移一下就好了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define MOD 1000000007
    void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int f[32][2][2][2],g[32][2][2][2];
    int Calc(int L,int R,int K)
    {
    	if(L<0||R<0)return 0;
    	memset(f,0,sizeof(f));memset(g,0,sizeof(g));f[31][0][0][0]=1;
    	for(int i=30;~i;--i)
    		for(int a=0;a<=1;++a)
    			for(int b=0;b<=1;++b)
    				for(int k=0;k<=1;++k)
    				{
    					if(!f[i+1][a][b][k])continue;
    					for(int A=0;A<=1;++A)
    						for(int B=0;B<=1;++B)
    						{
    							if(!a&&A&&!(L&(1<<i)))continue;
    							if(!b&&B&&!(R&(1<<i)))continue;
    							if(!k&&!(K&(1<<i))&&(A^B))continue;
    							int na=a,nb=b,nk=k;
    							if(!A&&(L&(1<<i)))na|=1;
    							if(!B&&(R&(1<<i)))nb|=1;
    							if(!(A^B)&&(K&(1<<i)))nk|=1;
    							add(f[i][na][nb][nk],f[i+1][a][b][k]);
    							add(g[i][na][nb][nk],g[i+1][a][b][k]);
    							if(A^B)add(g[i][na][nb][nk],1ll*(1<<i)*f[i+1][a][b][k]%MOD);
    						}
    				}
    	int ret=0;
    	for(int a=0;a<=1;++a)
    		for(int b=0;b<=1;++b)
    			for(int k=0;k<=1;++k)
    				add(ret,g[0][a][b][k]),add(ret,f[0][a][b][k]);
    	return ret;
    }
    int main()
    {
    	int Q=read();
    	while(Q--)
    	{
    		int x1=read()-1,x2=read()-1,y1=read()-1,y2=read()-1,k=read()-1;
    		int ans1=(Calc(y1,y2,k)+Calc(x1-1,x2-1,k))%MOD;
    		int ans2=(Calc(x1-1,y2,k)+Calc(y1,x2-1,k))%MOD;
    		int ans=(ans1+MOD-ans2)%MOD;
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    C# MJPEG 客户端简单实现
    CefSharp 实现多标签页 调用ChromiumWebBrowser的SetAsPopup()后浏览页卡死,的另一种解决方案
    opencv findContours 报错解决记录
    什么叫网关
    分别实现网页播放mp3、flv、wmv、Flash,代码兼容FireFox
    ToString()和Convert.ToString()的用法区别
    asp,asp.net中关于双引号和单引号的用法
    .NET中继承和多态深入剖析(上)
    ASP.NET中不常用的另类绑定方法<%$ %>
    C#日期函数所有样式大全
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10473561.html
Copyright © 2020-2023  润新知