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 微信支付教程系列之现金红包
微信支付教程系列之现金红包 最近最弄这个微信支付的功能,然后扫码.公众号支付,这些都做了,闲着无聊,就看了看微信支付的其他功能,发现还有一个叫“现金红包”的玩意,想 ...
随机推荐
- Swift-闭包理解(二)
简明扼要的闭包表达式 其实Swift已经为我们提供了很多简化的语法,可以让我们保证代码的高可读性和维护性.还用上面的例子来说明,对于 greetPeople 这个全局函数来说,其实只需要使用一次,所 ...
- OSG学习:矩阵变换节点示例
#include<osgViewer\Viewer> #include<osg\Node> #include<osg\Geode> #include<osg\ ...
- requests保持cookies的问题
获取cookie,返回CookieJar对象:url = 'http://www.baidu.com'r = requests.get(url) r.cookies#将CookieJar转为字典: c ...
- NeoLoad系列- 快速上手教程
1.新建工程 2.点击录制脚本按钮 3.在弹出的开始录制对话框中,填写虚拟用户信息. Record in下拉框,用来填写用户路径,一般有三个容器组成: Init, Actions, and End.当 ...
- Perfmon - Windows 自带系统监控工具
一. 简述 可以用于监视CPU使用率.内存使用率.硬盘读写速度.网络速度等. Perfmon提供了图表化的系统性能实时监视器.性能日志和警报管理,系统的性能日志可定义为二进制文件.文本文件.SQLSE ...
- C/S结构
C/S结构 编辑 同义词 C/S架构一般指C/S结构 C/S 结构,即大家熟知的客户机和服务器结构.它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Serv ...
- C的强制转换和C++的强制转换(转)
C的强制转换: (type)<expression> 其中,type为类型描述符,如int,float等.<expression>为表达式.经强制类型转换运算符运算后,返回一个 ...
- [剑指Offer] 61.序列化二叉树
题目描述 请实现两个函数,分别用来序列化和反序列化二叉树 /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *r ...
- MyBatis配置和日志
MyBatis最关键的组成部分是SqlSessionFactory,我们可以从中获取SqlSession,并执行映射的SQL语句.SqlSessionFactory对象可以通过基于XML的配置信息或者 ...
- hdu2295-Radar
有n个城市,\(m\)个雷达,\(k\)个操作员,每个操作员只能操作一个雷达.每个雷达的覆盖范围是一个以雷达坐标为中心的圆,所有雷达的覆盖半径是相同的. 现在给出这\(n\)个城市,\(m\)个雷达的 ...