CodeForces 635C XOR Equation

位运算。

又涨姿势了:$a + b = (aXORb) + 2*(aANDb)$,$ (aXORb)$是不进位的部分,$2*(aANDb)$为进位之后的部分,相加就是$a + b$。

知道了这个转换,这题就很容易了。设$n=a+b$,$m=(aXORb)$,$x=(aAND b)$;$n$、$m$和$x$都是已知的。

题目要求统计有多少$(a,b)$满足:

$\left\{ {\begin{array}{*{20}{c}}
{a + b = n}\\
{aXORb = m}
\end{array}} \right.$

等价于统计有多少$(a,b)$满足:

$\left\{ {\begin{array}{*{20}{c}}
{aAND b = x}\\
{aXORb = m}
\end{array}} \right.$

因此,可以按位统计,然后乘法原理乘一下就得到了答案。如果$n=m$,答案还需要减$2$,因为多统计了$0$ $n$和$n$ $0$。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<bitset>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) {x=x*10+c-‘0‘; c=getchar();}
}

LL n,m,ans=1;
LL b[50],c[50];

int main()
{
    cin>>n>>m;
    if(m>n) { printf("0\n"); return 0; }
    if((n-m)%2!=0) { printf("0\n"); return 0; }

    b[0]=1; for(int i=1;i<=40;i++) b[i]=2*b[i-1];

    LL x=(n-m)/2;
    for(int i=0;i<=40;i++)
    {
        for(int s1=0;s1<=1;s1++)
        {
            for(int s2=0;s2<=1;s2++)
            {
                LL f1,f2;
                if((m&b[i])) f1=1; else f1=0;
                if((x&b[i])) f2=1; else f2=0;
                if((s1^s2)!=f1) continue;
                if((s1&s2)!=f2) continue;
                c[i]++;
            }
        }
    }

    for(int i=0;i<=40;i++) ans=ans*c[i];
    if(n==m) ans=ans-2;

    cout<<ans<<endl;

    return 0;
}
时间: 2024-12-16 06:12:14

CodeForces 635C XOR Equation的相关文章

Codeforces 627A XOR Equation(思路)

题目大概说两个正整数a.b,已知s=a+b以及x=a xor b的值,问有几种a.b这样的数对. 我知道异或相当于无进位的加法,s-x就是其各个位置的进位,比如s-x=1010,那就表示a和b的第1位和第3位发生的进位. 这样,对于某些位其值就能确定,对于有些位其值不能确定(该位xor和为1且没有发生进位),这时a和b的该位都能选择0或者1,对于不确定的就是乘法原理答案累乘2. 另外还有一些情况是不可能的,首先s<x不可能,s-x是奇数不可能,某一位xor和是1且发生了进位这不可能. 最后注意是

codeforces 242E. XOR on Segment 线段树

题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵线段树就可以. 每一次异或, 对于给定的x, 如果x的第i位是1, 那么就将第i棵线段树在给定的区间内0,1翻转, 这是很基础的操作. 对于区间求和操作, 我们可以求出给定的区间, 从高位到低位, 每一位依次有多少个1, 然后就可以直接求出来, 感觉不好表达....具体看代码. 1 #include

Codeforces 242E. XOR on Segment (二维线段树 lazy操作 xor)

题目链接: http://codeforces.com/problemset/problem/242/E 题意: 给出一个序列,有两种操作,一种是计算l到r的和,另一种是让l到r的数全部和x做异或运算. 思路: from: http://blog.csdn.net/u013912596/article/details/39006317 很显然直接暴力是不可能的,又是两种操作,又想到了线段树..但是这并不简单,异或操作该怎么处理? 异或是一种位运算,如果x的第j位是1,那么说明l到r的每个数的第j

CodeForces - 617E XOR and Favorite Number (莫队+前缀和)

Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is given by a pair li and ri and asks you to count the number of pairs of integers i and j, such that l ≤ i ≤ j ≤ r and the xor of the numbers ai, ai + 1,

(莫队算法)CodeForces - 617E XOR and Favorite Number

题意: 长度为n的数列,m次询问,还有一个k.每次询问询问询问从数列的L到R内有多少个连续子序列异或起来等于k. 分析: 因为事先知道这题可以用莫队写,就正好用这题练习莫队. 预处理每个前缀异或和. 然后莫队按分块排序后,不断更新,用一个数组cnt[]记录当前L到R前缀和的数量. R向右拉,新增的数量就是cnt[pre^k],pre表示当前这个R位置的前缀异或和,然后更新一下cnt. 其他的也类似. 算是一个比较好的入门题. 代码: 1 #include <cstdio> 2 #include

CodeForces 617E XOR and Favorite Number

莫队算法. #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn=100000+10; int a[maxn],pre[maxn]; long long cnt[20*maxn]; int pos[maxn]; int n,m,k; long long ans[maxn]; long long Ans

Codeforces 242E. XOR on Segment

题目大意: 给出一个序列,有两种操作,一种是计算l到r的和,另一种是让l到r的数全部和x做异或运算. 做法: 很显然直接暴力是不可能的(但是这题刚刚出来的时候,很多人用暴力水过去了,后来加强的数据吧),又是两种操作,又想到了线段树..但是这并不简单,异或操作该怎么处理? 异或是一种位运算,如果x的第j位是1,那么说明l到r的每个数的第j位都要反转,(0^1=1,1^1=0),如果是0,那么不变.既然是位运算,那么可不可以将每一位作为线段树单独维护呢? 好像可以呢!异或操作的话,相当于是一种区间操

[Codeforces 919E]Congruence Equation

Description 题库链接 求满足 \[n\cdot a^n\equiv b \pmod{p}\] 的 \(n\) 的个数, \(1\leq n\leq x\) , \(a,b,p,x\) 均已给出. \(2\leq p\leq 10^6+3,1\leq a,b < p, 1\leq x\leq 10^{12}\) , 保证 \(p\) 是质数. Solution 对于 \(x\leq 10^{12}\) 显然不能枚举判断.但我们注意到当关于 \(n_1,n_2\) 的方程,若满足 \(n

CF627A Xor Equation

题意:a+b=s,a^b=x(异或).问有多少有序Z+对(a,b)满足条件. 标程: 1 #include<cstdio> 2 using namespace std; 3 typedef long long ll; 4 ll s,x,cnt,t,fl; 5 int main() 6 { 7 scanf("%lld%lld",&s,&x); 8 t=(s-x)/2; 9 if ((t&x)||t<0||((s-x)&1)) return