AcWing 216 Rainbow signal

The meaning of problems

Given a sequence of length n, then the \ (1 \ sim N \) which select the number of the two numbers N \ (L, R & lt \) , if the \ (L> R & lt \) , then the switch \ (L , r \) . The section \ (L \) number to the second \ (R & lt \) number constitutes a series taken out.
A number of columns and for xor desired
B and that the number of columns and a desired
C or for the number of columns and a desired
\ (1 \ le N \ le 1e5, N natural number not more than 1E9 \)

analysis

  1. Bit arithmetic is to carry simultaneously and you, it is possible to have the natural number N is divided into 31 separate calculated
  2. Those \ ([l, r] \ ) a width of 1, the probability of a single selected actually as \ (1 \ over {N ^ 2} \) , and the others are \ (2 \ over {N ^ 2} \) . Width can be processed to those sections 1

Method ABC specific requirements:

  1. xor think that is the worst, but reading it is quite easy to understand, the use of two variables \ (c_1, c_2 \) to record from \ (r-1 \) the number of forward backwards, and even the odd segment segment and length (1 will experience as inverted XOR answer, so each segment is a number of 0 plus 1)
  2. and with or is the seek better, last0 last1 were recorded and the closest positions 0 and 1,
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef long long ll;
int a[N];
int n;
ll nn;
double B,C,A;
void calc(int x){
    int last1 = 0,last0 = 0;
    int c1 = 0,c2 = 0;
    double solo = 0;//区间宽度为1的
    for(int i=1;i<=n;i++){
        int k = a[i] >> x & 1;//k表示当前这一位是0还是1
        if(k){
            B += 2.0 * (i - last0 - 1) * (1 << x) / nn ;
            C += 2.0 * (i - 1) * (1 << x) / nn;
            A += 2.0 * c1 * (1 << x) / nn;
            c1++;
            swap(c1,c2);
            solo += (1 << x) * 1.0 / nn;
            last1 = i;
        }
        else{
            C += 2.0 * last1 * (1 << x) / nn;
            c1++;
            A += 2.0 * c2 * (1 << x) / nn;
            last0 = i;
        }
    }
    B += solo;
    C += solo;
    A += solo;
}
int main(){
    scanf("%d",&n); nn = (ll) n * n;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=0;i<31;i++){
        calc(i);
    }
    printf("%.3f %.3f %.3f\n",A,B,C);
    return 0;
}

Guess you like

Origin www.cnblogs.com/1625--H/p/11427020.html