zoukankan      html  css  js  c++  java
  • POJ3495 Bitwise XOR of Arithmetic Progression

    Time Limit: 5000MS   Memory Limit: 131072K
    Total Submissions: 772   Accepted: 175

    Description

    Write a program that, given three positive integers xy and z (xyz < 232x ≤ y), computes the bitwise exclusive disjunction (XOR) of the arithmetic progression xx + zx + 2z, …, x + kz, where k is the largest integer such that x + kz ≤ y.

    Input

    The input contains multiple test cases. Each test case consists of three integers xyz separated by single spaces on a separate line. There are neither leading or trailing blanks nor empty lines. The input ends once EOF is met.

    Output

    For each test case, output the value of  on a separate line. There should be neither leading or trailing spaces nor empty lines.

    Sample Input

    2 173 11

    Sample Output

    48

    Source

     
     
    数学问题 解析几何 递归
     
    我可能开了假的公式支持……latex公式全都炸了,迷
    upd:发现markdown编辑器的latex和这里的latex好像不太兼容,用CSDN的markdown写好公式复制过来不识别,复制到记事本里清一下文本格式再复制回来就好了
     

    异或的每一位是独立的,所以可以分别计算每一位的答案。

    假设现在正在处理的二进制位为 $ 2 ^ i $ ,我们需要计算

    ( left lfloor frac{x}{2^i} ight floor + left lfloor frac{x+z}{2^i} ight floor + left lfloor frac{x+2z}{2^i} ight floor + left lfloor frac{x+3z}{2^i} ight floor + [f(x)] + left lfloor frac{x+(n-1)z}{2^i} ight floor )

    好麻烦啊,换个表示方法:

    ( a=z )

    $ b=x $

    $ c=2^i $

    $ans=sum_{x=0}^{n-1} left lfloor frac{ax+b}{c} ight floor$

    $ans=sum_{x=0}^{n-1} (left lfloor frac{ax}{c} ight floor +left lfloor frac{b}{c} ight floor +left lfloor frac{(a\%c)*x+b\%c}{c} ight floor) $ (1)

    前两项可以提出来用等差数列求和公式算,后一项看着有点麻烦啊

    把后一项画出来是这个样子:

    发现我们要算的是直线下面的整点的数量,即图中的蓝点数。

    为了方便地计算蓝点,重建直角坐标系,像下面那样:

    原来的直线方程是

    $ frac{(a\%c) * x + b\%c)}{c} $

    现在变成了

    $ frac{cx+(an+b)\%c}{a\%c} $

    (斜率取倒数,再算一下x0到n的距离作为截距)

    那么

    $ ans=sum_{x=0}^{n-1} left lfloor frac{ax+b}{c} ight floor =sum_{x=0}^{lfloor (a\%c)n+(b\%c)/c +1 floor} lfloor frac{cx+(an+b)\%c}{a\%c} floor $

    可以发现这是一个可以递归计算的形式。

    所以每次递归处理余下的部分,累加计算(1)式的前两项,算出这一位的值以后,判断二进制的这一位是奇数还是偶数,统计最终答案。

    计算会爆int。

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #define LL long long
     8 using namespace std;
     9 LL calc(LL a,LL b,LL c,LL n){
    10     if(!n)return 0;
    11     LL tmp=(LL)a/c*n*(n-1)/2;
    12     tmp+=(LL)b/c*n;
    13     return tmp+calc(c,(a*n+b)%c,a%c,((a%c)*n+b%c)/c);
    14 }
    15 int main(){
    16     LL x,y,z;
    17     while(scanf("%lld%lld%lld",&x,&y,&z)!=EOF){
    18         LL ans=0;
    19         for(int i=31;i>=0;i--){
    20             ans|=(calc(z,x,1ll<<i,((LL)y-x+1+z-1)/z)&1ll)<<i;
    21         }
    22         printf("%lld
    ",ans);
    23     }
    24     return 0;
    25 }
  • 相关阅读:
    pandas Dataframe filter
    process xlsx with pandas
    data manipulate in excel with easyExcel class
    modify registry in user environment
    add number line in vim
    java import webservice
    ctypes MessageBoxA
    music 163 lyrics
    【python实例】自动贩卖机
    【python基础】sys模块(库)方法汇总
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6798249.html
Copyright © 2011-2022 走看看