日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Rinne Loves Xor

發(fā)布時(shí)間:2023/12/3 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Rinne Loves Xor 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

鏈接:

來(lái)源:牛客網(wǎng)

時(shí)間限制:C/C++ 2秒,其他語(yǔ)言4秒 空間限制:C/C++ 262144K,其他語(yǔ)言524288K 64bit IO Format: %lld

題目描述

輸入描述:
第一行一個(gè)整數(shù) N,表示數(shù)組 A 和 B 的長(zhǎng)度。
第二行 N 個(gè)整數(shù)表示數(shù)組 A。
第三行 N 個(gè)整數(shù)表示數(shù)組 B。
輸出描述:
輸出一行 N 個(gè)整數(shù),表示加密后的數(shù)組 C。
示例1
輸入
復(fù)制

10 65605 70259 77306 43823 61443 98602 9261 7662 46394 83019 81393 5966 61479 24259 92528 96132 35859 47981 11702 71736

輸出
復(fù)制

15796 166270 623824 1132402 1650729 2445262 3256941 4150718 5106184 6353038

備注:
N≤105, ai≤109

題解:

本人也沒(méi)做出來(lái),看了其他題解,學(xué)到兩個(gè)方法

方法一

參考題解
一下為個(gè)人結(jié)合題解的理解
暴力做O(n2)肯定超時(shí)

題目已經(jīng)發(fā)式子給我們了,我們可以看出整個(gè)求解其實(shí)就是一個(gè)遞推過(guò)程。由已知推位置,之前推出的后面也不會(huì)再修改。
異或:相同為0,不同為非0
最麻煩的就是后面這個(gè)部分
這個(gè)累加式子我們可以拆開(kāi)

既然是異或,我們就用二進(jìn)制來(lái)考慮,a與b異或,我們也可以把a(bǔ)與b都分成二進(jìn)制,題目給的a的范圍小于1e9,也就是a二進(jìn)制最多為32位,所以這樣完全ok
兩個(gè)數(shù)位不同為1,如果當(dāng)前數(shù)字二進(jìn)制是1,前面這個(gè)數(shù)的這個(gè)位置的數(shù)如果是0,就可以貢獻(xiàn)出1;反之也是。如果兩個(gè)相同,則無(wú)法貢獻(xiàn)
我們用到一個(gè)sum數(shù)組
sum[i][0]

sum1[i][0] 表示前面的 a 數(shù)組中二進(jìn)制第 i 位為0 的數(shù)目
sum1[i][1]sum1[i][1] 表示前面的 a 數(shù)組中二進(jìn)制第 i 位為 1 的數(shù)目
sum2[i][0]sum2[i][0] 表示前面的 b 數(shù)組中二進(jìn)制第 i 位為 0 的數(shù)目
sum2[i][1]sum2[i][1] 表示前面的b 數(shù)組中二進(jìn)制第 i 位為 1 的數(shù)目

#include<bits/stdc++.h> using namespace std;const long long inf = 1e18; const int N = 1e6 + 5; const double eps = 1e-10; const int mod = 1e9 + 7; typedef long long ll;ll a[N], b[N]; ll ans[N]; ll sum1[64][2], sum2[64][2]; ll qpow(ll a, ll b) {ll res = 1;while(b) {if(b & 1) {res = res * a % mod;}a = a * a % mod;b >>= 1;}return res; } int main() {int n;cin >> n;for(int i = 1; i <= n; i++) cin >> a[i];for(int i = 1; i <= n; i++) cin >> b[i];for(int i = 1; i <= n; i++) {ll p = ans[i - 1] + (a[i] ^ b[i]) % mod;for(int j = 0; j <= 32; j++) {if(a[i] & (1LL << j)) { // 該位為1p += qpow(2, j) * sum2[j][0] % mod;}else { // 該位為0p += qpow(2, j) * sum2[j][1] % mod;}//cout << j << ' ' << sum2[j][0] << ' ' << sum2[j][1] << "\n";}for(int j = 0; j <= 32; j++) {if(b[i] & (1LL << j)) { // 該位為1p += qpow(2, j) * sum1[j][0] % mod;}else { // 該位為0p += qpow(2, j) * sum1[j][1] % mod;}}ans[i] = p % mod;for(int j = 0; j <= 32; j++) {if(a[i] & (1LL << j)) {sum1[j][1]++;}else sum1[j][0]++;}for(int j = 0; j <= 32; j++) {if(b[i] & (1LL << j)) {sum2[j][1]++;}else sum2[j][0]++;}}for(int i = 1; i <= n; i++) {cout << ans[i] % mod << " \n"[i == n];}return 0; }

方法二:

個(gè)人感覺(jué)和上一個(gè)方法處理思想其實(shí)差不多
也是分成二進(jìn)制進(jìn)行對(duì)應(yīng)數(shù)位異或
式子:
Ci=Ci-1+ai xor b1+ai xor b2+…ai xor bi +ai-1 xor bi +…a1 xor bi

如果當(dāng)前位數(shù)j,之前出現(xiàn)過(guò)4次1,另外一組出現(xiàn)過(guò)3次0,那么后面計(jì)算這一位給答案貢獻(xiàn)就會(huì)是(4 * 3)<< j

pa[j][0/1]和pb[j][0/1]分別是a和b的在第j位之前0/1的數(shù)量
有個(gè)式子為
c[i] += (pa[j][0] * pb[j][1] + pa[j][1] * pb[j][0]) << j;
括號(hào)里就是相對(duì)應(yīng)數(shù)位的數(shù)進(jìn)行異或,而后面的<<j就是把這個(gè)數(shù)位的二進(jìn)制轉(zhuǎn)化成對(duì)應(yīng)的十進(jìn)制加給c

#include <iostream> using namespace std; typedef long long ll;const int MOD = 1e9 + 7; const int maxn = 1e5 + 2; ll a[maxn], b[maxn], c[maxn]; ll pa[37][2], pb[37][2];int main() {int n; cin>>n; for (int i = 1; i <= n; i++) cin>>a[i];for (int i = 1; i <= n; i++) cin>>b[i];for (int i = 1; i <= n; i++)for (int j = 0; j <= 30; j++) {pa[j][(a[i] >> j) & 1]++;pb[j][(b[i] >> j) & 1]++;//c[i] += (pa[j][0] * pb[j][1] + pa[j][1] * pb[j][0]) << j;c[i] %= MOD;}for (int i = 1; i <= n; i++)printf("%lld ", c[i]);return 0; }

總結(jié)

以上是生活随笔為你收集整理的Rinne Loves Xor的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。