ZROI #364. 【2018普转提day18专题】嘤嘤嘤

直接贴代码

具体见注释

#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=0,f=1;char c=getchar();
while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
} const int maxn=100100,maxm=55;
ll n,m,s,t;
ll tot[maxm][maxn],f[maxm][maxn][2];
ll a[maxn],q[maxn],lim,start; ll dfs(int x,int y,int z,ll tmp=0){
//当前确定了后x位,加的数是tmp时第x位上有y个数发生了进位,是否超过了限制lim(z=0/1)
if(x==m) return !z; //如果枚举完了,就看当前加的数是否可行
if(f[x][y][z]!=-1) return f[x][y][z];
ll nw=0;
int a=tot[x][y],b=y-a,c=tot[x][n]-a,d=n-y-c;
//a表示按照后x位排序后前y个数有几个第x+1位上是1,这时候a所代表的的数这一位为1且前一位发生了进位,那么这一位实际上会变成0
//b表示有几个数发生了进位但是这一位不是1
//c表示有几个数这一位是1但是没有进位,在当前情况下b和c代表的数是等价的
//d表示剩余的数(既没进位也不是1)的个数
int t=(s>>x)&1; //t表示s的这一位是啥
//现在有a+d个数这一位是0,b+c个数这一位是1
if(((b+c)&1)==t) nw+=dfs(x+1,a,((lim>>x)&1)?0:z,tmp); //这一位放0
if(((a+d)&1)==t) nw+=dfs(x+1,a+b+c,((lim>>x)&1)?z:1,tmp+(1<<x)); //这一位放1
return f[x][y][z]=nw;
} ll solve(ll x){
lim=x;
memset(f,-1,sizeof(f));
return dfs(0,0,0);
}
int main(){
n=read(),m=read(),s=read(),t=read();
rep(i,1,n){
a[i]=read();
start^=a[i];
}
rep(i,0,m-1){
rep(j,1,n)
tot[i][j]=tot[i][j-1]+((a[j]>>i)&1);
int nums=0;
rep(j,1,n)
if((a[j]>>i)&1) q[++nums]=a[j];
rep(j,1,n)
if(!((a[j]>>i)&1)) q[++nums]=a[j];
swap(a,q);
//q表示原来的数按照后i+1位排序之后的结果
//tot表示原来的数按照后i位排序之后,第i位上前j个数里有几个1
}
printf("%lld\n",solve((1ll<<m)-1)*(t>>m)+solve(t%(1ll<<m))-(start==s));
return 0;
}

Review

为什么这么做?

首先按位考虑,这个很好想

然后我就没思路了

没有想到数位dp。。。

而且对于每个长度为j的后缀的处理很巧妙

ZROI #364. 【2018普转提day18专题】嘤嘤嘤的更多相关文章

  1. ZROI #365. 【2018普转提day18专题】嘤嘤嘤嘤

    ZROI #365. [2018普转提day18专题]嘤嘤嘤嘤 直接放代码 具体做法见注释 #include<stdio.h> #include<cstring> #inclu ...

  2. ZR普转提2

    ZR普转提2 A 谢谢刁神教我A题 刚开始读错题了,以为是一个不可做的数位DP,然后就暴力滚粗 直到问了问刁神,发现自己题意是错的 然后成了比较简单的题目 直接暴力枚举每一位填什么,剩下的位数的数字都 ...

  3. ZR9.8普转提

    ZR9.8普转提 A,B 打过的CF原题,不管了 C 确认过眼神,是我不会写的DP, 发现这个题目要求的过程类似与一个所有括号都不一样的括号匹配的过程 但是限制条件非常多,有点无从下手的感觉 我们设\ ...

  4. 普转提——有趣的数,欢乐ABC,打游戏

    有趣的数——构造符合条件的数 给你一个区间,问有多少个数符合每一位中,只有一个数字和其他数字不同,也就是其他数字都相同,有且只有一个异类: 数据范围是1e16: 因为只考虑数量而不用管大小: 只要0到 ...

  5. ZROI2018普转提day6t1

    传送门 分析 记录区间最大值,线段树上二分找比这个点大的最靠前位置即可 代码 #include<iostream> #include<cstdio> #include<c ...

  6. ZROI2018普转提day6t3

    传送门 分析 居然卡哈希数,万恶的出题人...... 感觉我这个方法似乎比较呆,我的代码成功成为了全网最慢的代码qwq 应该是可以直接哈希的 但由于我哈希学的不好又想练练线段树维护哈希,于是就写了个线 ...

  7. ZROI2018普转提day7t1

    传送门 分析 一道有意思的小题... 我们发现如果$(1,1)$为白色,则将其变为白色需要偶数次操作,而如果为黑色则需要奇数次操作 我们知道要让A赢需要奇数次操作,所以我们只需要判断$(1,1)$的颜 ...

  8. ZROI2018普转提day7t2

    传送门 分析 首先我们不难想到我们一定可以将每一个点分开算,然后看这个点被几个矩形包含 于是对于位置为$(i,j)$的点它被包含的次数为$i * (n-i+1) * j * (m-j+1)$ 这个式子 ...

  9. ZROI2018普转提day1t4

    传送门 分析 就是飞飞侠这道题...... 我们可以将这张图建成好几层,每一层可以向下一层的上下左右无代价移动,而对于每个点如果付b[i][j]的代价就可以走到比它高a[i][j]的层上.我们用这种方 ...

随机推荐

  1. apache配置文件详解及虚拟主机的搭建

    1.404跳转: <IfModule dir_module>    DirectoryIndex index.php index.html /error.php</IfModule& ...

  2. Linux下MySQL、Apache、PHP源码安装全程实录(CentOS 6.4)

    转自http://www.zjmainstay.cn/lamp-config 本文记录了我自己配置LAMP的全过程,借此记录一下,同时希望能够帮助一下需要帮助的LINUX新人,跟我一起学习,一起进步. ...

  3. MySQL学习笔记(四)——分组数据group by子句和having子句

    分组允许把数据分为多个逻辑组,以便对每个组进行聚集计算. 例如我们查下每个系里有多少名学生: 在使用group by 子句之前,还需要知道一些规定: 1. group by 子句可以包含任意数目的列, ...

  4. 一篇文章看懂iOS代码块Block

    block.png iOS代码块Block 概述 代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量.作为参数.作为返 ...

  5. BZOJ 1633 [Usaco2007 Feb]The Cow Lexicon 牛的词典:dp【删字符最少】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1633 题意: 给你一个长度为n的主串a,和一个有m个字符串s[i]的单词书(s[i].si ...

  6. css中块元素和行内元素区别

    行内元素特点 1.和其他元素都在一行上: 2.元素的高度.宽度.行高及顶部和底部边距不可设置: 3.元素的宽度就是它包含的文字或图片的宽度,不可改变. 块元素特点 1.每个块级元素都从新的一行开始,并 ...

  7. js 分享代码--完整示例代码

    <div class="bdsharebuttonbox" data-tag="share_1"> <a class="bds_ms ...

  8. 【C/C++】任意大于1的整数分解成素数因子乘积的形式

    // #include<stdio.h> #include<math.h> #include<malloc.h> int isprime(long n); void ...

  9. java-swing-JTextComponent

    package com.http; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Swi ...

  10. MongoDB 3.2复制集单节点部署(四)

    MongoDB在单节点中也可以做复制集,但是仅限于测试实验,最大的好处就是部署方便快速,可以随便添加新节点,节省资源.在这里我使用的是MongoDB 3.2版本进行复制集实验(但MongoDB配置文件 ...