国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

51Nod - 1674 分治

2019-11-14 08:45:17
字體:
供稿:網(wǎng)友

題意:

lyk擁有一個(gè)區(qū)間。它規(guī)定一個(gè)區(qū)間的價(jià)值為這個(gè)區(qū)間中所有數(shù)and起來的值與這個(gè)區(qū)間所有數(shù)or起來的值的乘積。例如3個(gè)數(shù)2,3,6。它們and起來的值為2,or起來的值為7,這個(gè)區(qū)間對(duì)答案的貢獻(xiàn)為2*7=14。現(xiàn)在lyk有一個(gè)n個(gè)數(shù)的序列,它想知道所有n*(n+1)/2個(gè)區(qū)間的貢獻(xiàn)的和對(duì)1000000007取模后的結(jié)果是多少。例如當(dāng)這個(gè)序列為{3,4,5}時(shí),那么區(qū)間[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]的貢獻(xiàn)分別為9,0,0,16,20,25。Input
第一行一個(gè)數(shù)n(1<=n<=100000)。接下來一行n個(gè)數(shù)ai,表示這n個(gè)數(shù)(0<=ai<=10^9)。Output
一行表示答案。Input示例
33 4 5Output示例
70

思路:

完全沒思路,看網(wǎng)上題解的。分治,這方面能力還是弱。對(duì)于一段區(qū)間[l,r],求出中點(diǎn)mid,然后遞歸解決[l,mid-1]和[mid,r]的子問題,還有就是題目所要求的區(qū)間左端點(diǎn)在[l,mid-1],右端點(diǎn)在[mid,r]的情況,這里其實(shí)就是在[l,mid-1]中枚舉左端點(diǎn),然后在[mid,r]中枚舉右端點(diǎn)。這里關(guān)鍵要注意到,在求[mid,r]內(nèi)的and前綴和以及or前綴和會(huì)發(fā)現(xiàn)大部分的值都是相同的,因?yàn)?e9的二進(jìn)制位數(shù)只有大約log(1e9)位,這樣只要把[mid,r]區(qū)間的前綴和的值壓縮一下,數(shù)值相同的一段看作一個(gè)數(shù),并把這段長度儲(chǔ)存在cnt數(shù)組中,這樣前綴和長度不會(huì)超過log(1e9)。這樣再對(duì)[l,mid-1]區(qū)間遍歷一遍,對(duì)每個(gè)位置再暴力掃一遍[mid,r]的前綴和,復(fù)雜度是O(n*logn)。這樣分治,最后總復(fù)雜度是O(nlognlogn)。

代碼:

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int MAXN = 1e5 + 10;const ll MOD = 1e9 + 7;ll ans;ll a[MAXN], cnt[MAXN], OR[MAXN], AND[MAXN];void solve(int l, int r) {    if (l == r) return;    int mid = (l + r + 1) >> 1;    int pos = mid;    OR[pos] = AND[pos] = a[mid];    cnt[pos] = 1;    for (int i = mid + 1; i <= r; i++) {        if (OR[pos] != (OR[pos] | a[i]) || AND[pos] != (AND[pos] & a[i])) {     //   當(dāng)前and(or)前綴和與前一個(gè)and(or)前綴和不一致。            ++pos;            OR[pos] = OR[pos - 1] | a[i];            AND[pos] = AND[pos - 1] & a[i];            cnt[pos] = 1;        }        else ++cnt[pos];    }    ll resor = a[mid - 1], resand = a[mid - 1];    for (int i = mid - 1; i >= l; i--) {        resor |= a[i];        resand &= a[i];        for (int j = mid; j <= pos; j++) {            ans = (ans + (resor | OR[j]) * (resand & AND[j]) % MOD * cnt[j] % MOD) % MOD;        }    }    solve(l, mid - 1);    solve(mid, r);}int main() {    int n;    scanf("%d", &n);    ans = 0;    for (int i = 1; i <= n; i++) {        scanf("%I64d", &a[i]);        ans = (ans + a[i] * a[i] % MOD) % MOD;    }    solve(1, n);    PRintf("%I64d/n", ans);    return 0;}
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 靖边县| 杭州市| 新竹县| 玉环县| 平和县| 上虞市| 读书| 大新县| 平罗县| 祁东县| 广河县| 云龙县| 海城市| 阿瓦提县| 安多县| 高唐县| 和政县| 清新县| 三门县| 托克逊县| 天柱县| 景泰县| 海城市| 礼泉县| 衡阳县| 红桥区| 乃东县| 蓝田县| 马龙县| 五大连池市| 保亭| 阿城市| 江都市| 依安县| 永泰县| 含山县| 和静县| 古丈县| 资溪县| 东乡| 德清县|