题目链接

题面:

题意:
求解符合 x∈[0,a],y∈[0,b]x\in[0,a],y\in[0,b]x∈[0,a],y∈[0,b] 且 ∣x−y∣≤k|x-y|\le k∣x−y∣≤k 且 xxory≤wx\ xor\ y \le wx xor y≤w 的 (x,y)(x,y)(x,y) 的数对数量。

题解:
①、官方题解:
将∣x−y∣≤k|x-y|\le k∣x−y∣≤k 拆为 y−x≤k且x−y≤ky-x\le k且x-y\le ky−x≤k且x−y≤k,再转化为 x+k≥y且y+k≥xx+k\ge y且y+k\ge xx+k≥y且y+k≥x

我们设
dp[bit][x≤a][y≤b][x+k≥y][进位][y+k≥x][进位][xxory≤w]dp[bit][x\le a][y\le b][x+k\ge y][进位][y+k\ge x][进位][x\ xor\ y\le w]dp[bit][x≤a][y≤b][x+k≥y][进位][y+k≥x][进位][x xor y≤w]

我们从低位往高位枚举。

bitbitbit 表示当前枚举到哪一位。
x≤ax\le ax≤a 表示 xxx 的范围。
y≤by\le by≤b 表示 yyy 的范围。
x+k≥yx+k\ge yx+k≥y 表示当前绝对值限制条件之一
进位进位进位 表示考虑了当前 bitbitbit 位,x+kx+kx+k 产生的进位
y+k≥xy+k\ge xy+k≥x 表示当前绝对值条件限制之一
进位进位进位 表示考虑了当前 bitbitbit 位,y+ky+ky+k 产生的进位
xxory≤wx\ xor\ y \le wx xor y≤w 表示 xxx 与 yyy 异或与 www 的关系。

时间复杂度大概是 O(能过)O(能过)O(能过)。

代码:

#pragma GCC optimize(2)
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
#include<unordered_map>
#include<set>
namespace onlyzhao
{#define ui unsigned int#define ll long long#define llu unsigned ll#define ld long double#define pr make_pair#define pb push_back#define lc (cnt<<1)#define rc (cnt<<1|1)#define len(x)  (t[(x)].r-t[(x)].l+1)#define tmid ((l+r)>>1)#define fhead(x) for(int i=head[(x)];i;i=nt[i])#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)>(y)?(y):(x))#define one(n) for(int i=1;i<=(n);i++)#define rone(n) for(int i=(n);i>=1;i--)#define fone(i,x,n) for(int i=(x);i<=(n);i++)#define frone(i,n,x) for(int i=(n);i>=(x);i--)#define fonk(i,x,n,k) for(int i=(x);i<=(n);i+=(k))#define fronk(i,n,x,k) for(int i=(n);i>=(x);i-=(k))#define two(n,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)#define ftwo(i,n,j,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)#define fvc(vc) for(int i=0;i<vc.size();i++)#define frvc(vc) for(int i=vc.size()-1;i>=0;i--)#define forvc(i,vc) for(int i=0;i<vc.size();i++)#define forrvc(i,vc) for(int i=vc.size()-1;i>=0;i--)#define cls(a) memset(a,0,sizeof(a))#define cls1(a) memset(a,-1,sizeof(a))#define clsmax(a) memset(a,0x3f,sizeof(a))#define clsmin(a) memset(a,0x80,sizeof(a))#define cln(a,num) memset(a,0,sizeof(a[0])*num)#define cln1(a,num) memset(a,-1,sizeof(a[0])*num)#define clnmax(a,num) memset(a,0x3f,sizeof(a[0])*num)#define clnmin(a,num) memset(a,0x80,sizeof(a[0])*num)#define sc(x) scanf("%d",&x)#define sc2(x,y) scanf("%d%d",&x,&y)#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define scl(x) scanf("%lld",&x)#define scl2(x,y) scanf("%lld%lld",&x,&y)#define scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)#define scf(x) scanf("%lf",&x)#define scf2(x,y) scanf("%lf%lf",&x,&y)#define scf3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)#define scs(x) scanf("%s",x+1)#define scs0(x) scanf("%s",x)#define scline(x) scanf("%[^\n]%*c",x+1)#define scline0(x) scanf("%[^\n]%*c",x)#define pcc(x) putchar(x)#define pc(x) printf("%d\n",x)#define pc2(x,y) printf("%d %d\n",x,y)#define pc3(x,y,z) printf("%d %d %d\n",x,y,z)#define pck(x) printf("%d ",x)#define pcl(x) printf("%lld\n",x)#define pcl2(x,y) printf("%lld %lld\n",x,y)#define pcl3(x,y,z) printf("%lld %lld %d\n",x,y,z)#define pclk(x) printf("%lld ",x)#define pcf2(x) printf("%.2f\n",x)#define pcf6(x) printf("%.6f\n",x)#define pcf8(x) printf("%.8f\n",x)#define pcs(x) printf("%s\n",x+1)#define pcs0(x) printf("%s\n",x)#define pcline(x) printf("%d**********\n",x)#define casett int tt;sc(tt);int pp=0;while(tt--)char buffer[100001],*S,*T;inline char Get_Char(){if (S==T){T=(S=buffer)+fread(buffer,1,100001,stdin);if (S==T) return EOF;}return *S++;}inline int read(){char c;int re=0;for(c=Get_Char();c<'0'||c>'9';c=Get_Char());while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();return re;}
};
using namespace onlyzhao;
using namespace std;const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e18;
const int mod=998244353;
const int p=mod;
const double eps=1e-8;
const double pi=acos(-1.0);
const int hp=13331;
const int maxn=400100;
const int maxm=100100;
const int maxp=100100;
const int up=31;
const int g=3;ll dp[40][2][2][2][2][2][2][2];
//dp[bit][x<=a][y<=b][x+k>=y][进位][y+k>=x][进位][x^y<=w]
ll a,b,k,w;
ll dfs(int bit,int xa,int yb,int xky,int f1,int ykx,int f2,int xyw)
{if(bit==up){if(xa&&yb&&(xky||!xky&&f1)&&(ykx||!ykx&&f2)&&xyw)return 1;else return 0;}if(dp[bit][xa][yb][xky][f1][ykx][f2][xyw]!=-1) return dp[bit][xa][yb][xky][f1][ykx][f2][xyw];ll ans=0;int kbit=(k>>bit)&1,wbit=(w>>bit)&1;int abit=(a>>bit)&1,bbit=(b>>bit)&1;for(int i=0;i<=1;i++){for(int j=0;j<=1;j++){int nowxa=(xa&&i<=abit)||(!xa&&i<abit),nowyb=(yb&&j<=bbit)||(!yb&&j<bbit);int nowxky=(xky&&(((i+kbit+f1)&1)>=j))||(!xky&&(((i+kbit+f1)&1)>j));int nowf1=(i+kbit+f1)>>1;int nowykx=(ykx&&(((j+kbit+f2)&1)>=i))||(!ykx&&(((j+kbit+f2)&1)>i));int nowf2=(j+kbit+f2)>>1;int nowxyw=(xyw&&((i^j)<=wbit))||(!xyw&&((i^j)<wbit));ans+=dfs(bit+1,nowxa,nowyb,nowxky,nowf1,nowykx,nowf2,nowxyw);}}return dp[bit][xa][yb][xky][f1][ykx][f2][xyw]=ans;
}int main(void)
{int tt;scanf("%d",&tt);while(tt--){scanf("%lld%lld%lld%lld",&a,&b,&k,&w);memset(dp,-1,sizeof(dp));printf("%lld\n",dfs(0,true,true,true,0,true,0,true));}return 0;
}

②、压缩两维状态:

我们将 ∣x−y∣≤k|x-y|\le k∣x−y∣≤k 的限制转化为 x−y+k>=0x-y+k>=0x−y+k>=0 且 y−x+k>=0y-x+k>=0y−x+k>=0

我们设:
dp[bit][limita][limitb][xxory≤w][上一位满足x−y+k>=0需要的补位][上一位满足y−x+k>=0需要的补位]dp[bit][limita][limitb][x\ xor\ y\le w][上一位满足x-y+k>=0需要的补位][上一位满足y-x+k>=0需要的补位]dp[bit][limita][limitb][x xor y≤w][上一位满足x−y+k>=0需要的补位][上一位满足y−x+k>=0需要的补位]

其中第 5、65、65、6 维取 −1,0,1-1,0,1−1,0,1 。当需要补位 <=−2<=-2<=−2 时,不可能再符合要求(因为若当前位需要补位 −2-2−2 ,那么下一位需要提供 +4+4+4 的贡献来抵消这 −2-2−2 的贡献,显然这是不可能的)。当需要补位 >=1>=1>=1 时,状态都是一致的。(因为这一位如果能多提供 >=1>=1>=1 的贡献,那么下一位就相当于多提供了>=2>=2>=2 的贡献,下一位至多提供 −1-1−1 的贡献,这样还有至少 111 的贡献能传递下去)

上一位需要补−1-1−1,那么这一位需要抵消−1∗2=−2-1*2=-2−1∗2=−2的贡献(抵消不了的可以继续传给再下一位抵消),上一位可以多出来111供使用,那么这一位可以使用1∗2=21*2=21∗2=2

时间复杂度 O(能过)O(能过)O(能过)

代码:

#pragma GCC optimize(2)
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
#include<unordered_map>
#include<set>
namespace onlyzhao
{#define ui unsigned int#define ll long long#define llu unsigned ll#define ld long double#define pr make_pair#define pb push_back#define lc (cnt<<1)#define rc (cnt<<1|1)#define len(x)  (t[(x)].r-t[(x)].l+1)#define tmid ((l+r)>>1)#define fhead(x) for(int i=head[(x)];i;i=nt[i])#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)>(y)?(y):(x))#define one(n) for(int i=1;i<=(n);i++)#define rone(n) for(int i=(n);i>=1;i--)#define fone(i,x,n) for(int i=(x);i<=(n);i++)#define frone(i,n,x) for(int i=(n);i>=(x);i--)#define fonk(i,x,n,k) for(int i=(x);i<=(n);i+=(k))#define fronk(i,n,x,k) for(int i=(n);i>=(x);i-=(k))#define two(n,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)#define ftwo(i,n,j,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)#define fvc(vc) for(int i=0;i<vc.size();i++)#define frvc(vc) for(int i=vc.size()-1;i>=0;i--)#define forvc(i,vc) for(int i=0;i<vc.size();i++)#define forrvc(i,vc) for(int i=vc.size()-1;i>=0;i--)#define cls(a) memset(a,0,sizeof(a))#define cls1(a) memset(a,-1,sizeof(a))#define clsmax(a) memset(a,0x3f,sizeof(a))#define clsmin(a) memset(a,0x80,sizeof(a))#define cln(a,num) memset(a,0,sizeof(a[0])*num)#define cln1(a,num) memset(a,-1,sizeof(a[0])*num)#define clnmax(a,num) memset(a,0x3f,sizeof(a[0])*num)#define clnmin(a,num) memset(a,0x80,sizeof(a[0])*num)#define sc(x) scanf("%d",&x)#define sc2(x,y) scanf("%d%d",&x,&y)#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define scl(x) scanf("%lld",&x)#define scl2(x,y) scanf("%lld%lld",&x,&y)#define scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)#define scf(x) scanf("%lf",&x)#define scf2(x,y) scanf("%lf%lf",&x,&y)#define scf3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)#define scs(x) scanf("%s",x+1)#define scs0(x) scanf("%s",x)#define scline(x) scanf("%[^\n]%*c",x+1)#define scline0(x) scanf("%[^\n]%*c",x)#define pcc(x) putchar(x)#define pc(x) printf("%d\n",x)#define pc2(x,y) printf("%d %d\n",x,y)#define pc3(x,y,z) printf("%d %d %d\n",x,y,z)#define pck(x) printf("%d ",x)#define pcl(x) printf("%lld\n",x)#define pcl2(x,y) printf("%lld %lld\n",x,y)#define pcl3(x,y,z) printf("%lld %lld %d\n",x,y,z)#define pclk(x) printf("%lld ",x)#define pcf2(x) printf("%.2f\n",x)#define pcf6(x) printf("%.6f\n",x)#define pcf8(x) printf("%.8f\n",x)#define pcs(x) printf("%s\n",x+1)#define pcs0(x) printf("%s\n",x)#define pcline(x) printf("%d**********\n",x)#define casett int tt;sc(tt);int pp=0;while(tt--)char buffer[100001],*S,*T;inline char Get_Char(){if (S==T){T=(S=buffer)+fread(buffer,1,100001,stdin);if (S==T) return EOF;}return *S++;}inline int read(){char c;int re=0;for(c=Get_Char();c<'0'||c>'9';c=Get_Char());while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();return re;}
};
using namespace onlyzhao;
using namespace std;const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e18;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1.0);
const int hp=13331;
const int maxn=200100;
const int maxm=100100;
const int maxp=100100;
const int up=100100;ll a,b,k,w;
ll dp[40][2][2][2][3][3];
//dp[bit][limita][limitb][x^y==w or x^y<w][上一位满足x-y+k>=0需要的补位][上一位满足y-x+k>=0需要的补位]
//其中第5、6维取-1,0,1 当需要补位 <=-2 时,不可能再符合要求。当需要补位 >=1 时,状态都是一致的。
//上一位需要补-1,那么这一位需要-1*2=-2的贡献,上一位可以多出来1供使用,那么这一位可以使用1*2=2
ll dfs(int bit,bool limitx,bool limity,bool xyw,int b1,int b2)
{if(bit==-1)return b1>=0&&b2>=0;if(b1<-1||b2<-1) return 0;if(dp[bit][limitx][limity][xyw][b1+1][b2+1]!=-1) return dp[bit][limitx][limity][xyw][b1+1][b2+1];int upa=limitx?(a>>bit)&1:1;int upb=limity?(b>>bit)&1:1;int kbit=(k>>bit)&1,wbit=(w>>bit)&1;ll ans=0;for(int x=0;x<=upa;x++){for(int y=0;y<=upb;y++){if(!xyw&&(x^y)>wbit) continue;ans+=dfs(bit-1,limitx&&x==upa,limity&&y==upb,xyw||(x^y)<wbit,min(2*b1+x-y+kbit,1),min(2*b2+y-x+kbit,1));}}return dp[bit][limitx][limity][xyw][b1+1][b2+1]=ans;
}int main(void)
{int tt;scanf("%d",&tt);while(tt--){scanf("%lld%lld%lld%lld",&a,&b,&k,&w);memset(dp,-1,sizeof(dp));printf("%lld\n",dfs(30,true,true,false,0,0));}return 0;
}

2020中国大学生程序设计竞赛(CCPC) - 网络选拔赛----HDU--6899、Xor(数位dp)相关推荐

  1. 2020年中国大学生程序设计竞赛(CCPC) - 网络选拔赛部分题解

    前言 既培养算法知识,又能学习按摩手法,我们还有专业的算命大师帮你窥察天机. 这还犹豫什么,快来加入我们.前10名还能请大师免费帮你看风水,让你死后也能安心. 我怕不是进了一个人才市场- Expres ...

  2. 2019中国大学生程序设计竞赛(CCPC)-网络选拔赛-第七题Shuffle Card

    文章目录 1.大赛题目 2.中文翻译 3.代码案例 4.解题思路 4.1代码举例 1.大赛题目 Shuffle Card Time Limit: 2000/1000 MS (Java/Others) ...

  3. 2020中国大学生程序设计竞赛(CCPC) - 网络选拔赛 1005 Lunch (杭电 6892)

    2020中国大学生程序设计竞赛(CCPC) - 网络选拔赛 1005 Lunch (杭电 6892)(类尼姆博弈) #include<cstdio> #include<iostrea ...

  4. 2021中国大学生程序设计竞赛(CCPC),烤仔与你不见不散!

    今天也是见到超多学霸的一天呢! 因为,CCPC 的参赛选手们来看烤仔啦!北京航空航天大学.北京交通大学等高校共 95 名总决赛参赛选手在 5 月 28 日来到 Conflux 参观.交流. 由中国大学 ...

  5. 2020中国大学生程序设计竞赛(CCPC)- 网络选拔赛 1002 Graph Theory Class

    题目链接 Problem Description This class is on graph theory. Mr. Kruskal teaches babies the concept of mi ...

  6. 2022第8届中国大学生程序设计竞赛CCPC威海站, 签到题7题

    文章目录 E.Python Will be Faster than C++ A.Dunai G.Grade 2 J.Eat, Sleep, Repeat C.Grass D.Sternhalma I. ...

  7. 2021第7届中国大学生程序设计竞赛CCPC广州站, 签到题4题

    文章目录 I.Pudding Store H.Three Integers C.Necklace F.Cactus 补题链接:https://codeforces.com/gym/103415 I.P ...

  8. 2021第7届中国大学生程序设计竞赛CCPC桂林站, 签到题5题

    文章目录 A.Hero Named Magnus I. PTSD G. Occupy the Cities E. Buy and Delete D.Assumption is All You Need ...

  9. 浙江大学计算机学院 英语竞赛 陈星,喜报 | 浙大代表队获得CCPC中国大学生程序设计竞赛冠军...

    浙江大学Wheatfield with Crows队在2019年10月20日下午2时结束的CCPC中国大学生程序设计竞赛厦门赛站中获得冠军,来自复旦大学和清华大学的队伍分获亚军和季军. 本次比赛于20 ...

最新文章

  1. android 自定义span_Android – 为ClickSpan设置自定义可绘制背景
  2. Android开发 Butterknife使用方法总结
  3. pdo 连接数据库 报错 could not find driver 解决方法
  4. WordPress翻译更新失败解决方法
  5. Unity MegaFiers 顶点动画
  6. java位运算(、|、 ~、、 、 ^)
  7. 免费素材:分享33套好看的网页按钮和图标素材
  8. 计算机基础知识题库选择题,计算机基础知识题库选择题
  9. IDM6.38使用教程 ——下载加速 百度云下载加速 捕获网页视频,音乐
  10. 智能网联汽车云控系统第5部分:平台服务场景规范
  11. [C++]判断齐次坐标系中三点是否共线(三个向量是否共面)
  12. 矢量、栅格、瓦片地图傻傻分不清
  13. 2念整数(5分) 题目内容: 你的程序要读入一个整数,范围是[-100000,100000]。然后,用汉语拼音将这个整数的每一位输出出来。 如输入1234,则输出: yi er san si
  14. 可以卸载什么程序来对计算机进行瘦身,怎么清理电脑内存-电脑越来越卡了,教你一分钟让电脑瘦身(C盘哪些文件可以删除)...
  15. 电子驻车系统(拉索式)
  16. 格兰仕滚筒洗衣机学习
  17. 分布式一致性算法 - raft 图解
  18. 低级程序员和高级程序员的区别在于?
  19. 元宇宙迷思:科幻世界内外,“元宇宙”都几乎没有意义……
  20. Vim中的常用命令总结(持续补充完善)

热门文章

  1. 2019.4.8 1532 Drainage Ditches
  2. Girls and Boys||HDU1068
  3. Detected problems with API compatibility(visit g.co/dev/appcompat for more info
  4. 《Graph Neural Networks Foundations,Frontiers and Applications》预备章节(名词)翻译和解读
  5. 2016年寒假读书笔记
  6. *CTF2022 oh-my-notepro
  7. 个人如何发表国家级期刊
  8. 第一个例子——纽约市出租车票价预测
  9. 计算机二级优秀英语,计算机二级用英语怎么说
  10. Verilog `define `timescale `include 浅谈