szoj657 【AHSDFZNOI 7.2 WuHongxun】Odd
【题目大意】
给出$n$个数$a_1, a_2, ..., a_n$,求有多少个区间$[l, r]$,满足每个数都出现了奇数次。
$1 \leq n \leq 2 * 10^5, 0 \leq a_i \leq 10^6$
【题解】
稳爷爷出的noi模拟题(原题来自某地区ioi选拔赛)
给每个数赋一个随机权值$H_x$,那么问题转化为:
有多少个区间,使得区间内的数的异或和=区间内出现过的数的异或和。
这是可以分块的,记$lst_i$表示数$i$上一次出现的位置,令$x = H_{a_i}$那么每次就是给$[1, lst_x]$异或一个数,并且询问$[1, i]$中为0的数的个数。
分块+map可以做到$O(n\sqrt{nlogn})$。但是会被卡。
分块+hash就能做到$O(n\sqrt{n})$了,把hash表的取模开到1000~3000较优。每次暴力就重构一次。重构的时空复杂度是正确的。
# include <map>
# include <vector>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 2e5 + , M = 1e6 + , NB = + ;
const int mod = 1e9+, BLOCK = ;
const int MOD = ; int n, m, B, a[N], bl[N], L[N], R[N];
vector<int> ps;
ull H[N];
int lst[N]; struct hasher {
int head[MOD + ], w[MOD + ], nxt[MOD + ], tot, id, hid[MOD + ]; ull to[MOD + ];
inline void set() {
tot = ; id = ;
memset(head, , sizeof head);
memset(hid, , sizeof hid);
}
inline void reset() {
tot = ; ++id;
}
inline void add(int u, ull v, int _w) {
++tot; nxt[tot] = head[u];
head[u] = tot; to[tot] = v; w[tot] = _w;
}
inline void init(int L, int R) {
add(, , R-L+);
} inline int bg(int x) {
if(hid[x] == id) return head[x];
else {
hid[x] = id;
return head[x] = ;
}
} inline void ins(ull x) {
int hx = x % MOD;
for (int i=bg(hx); i; i=nxt[i])
if(to[i] == x) {
++w[i];
return ;
}
add(hx, x, );
} inline int query(ull x) {
int hx = x % MOD;
for (int i=bg(hx); i; i=nxt[i])
if(to[i] == x) return w[i];
return ;
}
}solver[NB]; inline ull irand() {
ull ret = ;
for (int i=; i<=; ++i) ret = (ret << ) + rand();
return ret;
} ull tag[NB], c[N];
inline void dealxor(int x, ull v) {
if(!x) return ;
int p = bl[x];
for (int i=; i<p; ++i) tag[i] ^= v;
solver[p].reset();
for (int i=L[p]; i<=x; ++i) {
c[i] ^= v;
solver[p].ins(c[i]);
}
for (int i=x+; i<=R[p]; ++i) solver[p].ins(c[i]);
} inline int query(int x) {
int p = bl[x], ret = ;
for (int i=; i<p; ++i) ret += solver[i].query(tag[i]);
for (int i=L[p]; i<=x; ++i) if(c[i] == tag[p]) ++ret;
return ret;
} int main() {
// freopen("odd2.in", "r", stdin);
cin >> n;
for (int i=; i<=n; ++i) {
scanf("%d", a+i);
ps.push_back(a[i]);
}
sort(ps.begin(), ps.end());
ps.erase(unique(ps.begin(), ps.end()), ps.end());
m = ps.size();
for (int i=; i<=n; ++i) a[i] = lower_bound(ps.begin(), ps.end(), a[i]) - ps.begin() + ;
for (int i=; i<=m; ++i) H[i] = irand();
for (int i=; i<=n; ++i) bl[i] = (i-)/BLOCK + ;
B = bl[n];
for (int i=; i<=B; ++i) L[i] = (i-) * BLOCK + , R[i] = i * BLOCK;
R[B] = min(R[B], n);
for (int i=; i<=B; ++i) solver[i].set(), solver[i].init(L[i], R[i]);
ll ans = ;
for (int i=; i<=n; ++i) {
int pre = lst[a[i]]; lst[a[i]] = i;
// cerr << i << ' ' << pre << endl;
dealxor(pre, H[a[i]]);
ans += query(i);
}
cout << ans;
return ;
}
/*
4
2 2 2 3
Ans = 7
*/
szoj657 【AHSDFZNOI 7.2 WuHongxun】Odd的更多相关文章
- 【jQuery 冻结任意行列】冻结任意行和列的jQuery插件
实现原理: 创建多个div,div之间通过css实现层叠,每个div放置当前表格的克隆.例如:需要行冻结时,创建存放冻结行表格的div,通过设置z-index属性和position属性,让冻结行表格在 ...
- 进击的Python【第十六章】:Web前端基础之jQuery
进击的Python[第十六章]:Web前端基础之jQuery 一.什么是 jQuery ? jQuery是一个JavaScript函数库. jQuery是一个轻量级的"写的少,做的多&quo ...
- JAVA 基础编程练习题39 【程序 39 分数累加】
39 [程序 39 分数累加] 题目:编写一个函数,输入 n 为偶数时,调用函数求 1/2+1/4+...+1/n,当输入 n 为奇数时,调用函数 1/1+1/3+...+1/n package cs ...
- 【疯狂造轮子-iOS】JSON转Model系列之二
[疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...
- 【疯狂造轮子-iOS】JSON转Model系列之一
[疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...
- 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付
前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...
- 【AutoMapper官方文档】DTO与Domin Model相互转换(上)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- 【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】
由于个人研究需要,需要采集天气历史数据,前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),介绍了基本的采集思路和核心代码,经过1个星期的采集,历史数据库 ...
- 【原创分享·微信支付】C# MVC 微信支付教程系列之现金红包
微信支付教程系列之现金红包 最近最弄这个微信支付的功能,然后扫码.公众号支付,这些都做了,闲着无聊,就看了看微信支付的其他功能,发现还有一个叫“现金红包”的玩意,想 ...
随机推荐
- Delegate(QLabel和QComboBox)
一.最终效果 二.实现思路 1.createEditor()中create两个控件,分别是QLabel和QComboBox,将其添加到一个widget中,然后返回该widget: 2.setEdito ...
- DAY4敏捷冲刺
站立式会议 工作安排 (1)服务器配置 已完成对微信小程序登录凭证储存至云端数据库,计划使用微信接口返回的session_id进行转化返回本地,以保持登录态. (2)数据库配置 单词学习记录+用户信息 ...
- 二叉树及其遍历方法---python实现
github:代码实现 本文算法均使用python3实现 1. 二叉树 1.1 二叉树的定义 二叉树是一种特殊的树,它具有以下特点: (1)树中每个节点最多只能有两棵树,即每个节点的度最多为2 ...
- iOS- 显示数据列表最常用的一个控件UITableView
相信做过iOS的程序员,最熟悉的控件一定少不了UITableView,最常用的控件也一定少不了UITableView! 今天分享一下自己对UITableView的实现大体思路,和整理出来的学习笔记! ...
- lol人物模型提取(四)
在淘宝上联系了一个3d打印服务的卖家,他要我转成stl.obj.xt.xst.igs任意一种格式给他发过去,我就把它转成了obj格式给他发过去了. 然后他那边打开是这样的,没有贴图,看上去模型 ...
- activity属性设置大全
activity属性设置大全 android:allowTaskReparenting=["true" | "false"] 是否允许activ ...
- linux路由表的配置
linux路由表的配置 一.原理说明 1.路由表(table)从0到255进行编号,每个编号可以对应一个别名,编号和别名的对应关系在linux下放在/etc/iproute2/rt_tables这个文 ...
- [C/C++] 结构体存储问题
64位操作系统,不同类型变量对应的字节数为: char : 1个字节 char*(即指针变量) : 8个字节 //32位占4个字节 short int : 2个字节 int : 4个字节 unsign ...
- linux 装redmine
看第一篇 https://www.cnblogs.com/iluzhiyong/p/redmine.html 看第二篇 http://blog.51yip.com/cloud/1874.html 基本 ...
- P1278 单词游戏
题目描述 Io和Ao在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何一个单词开始. 任何单词禁止说两遍,游戏中只 ...