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 微信支付教程系列之现金红包
微信支付教程系列之现金红包 最近最弄这个微信支付的功能,然后扫码.公众号支付,这些都做了,闲着无聊,就看了看微信支付的其他功能,发现还有一个叫“现金红包”的玩意,想 ...
随机推荐
- Oracle ORA-12541:TNS:no listener错误解决方法 (转)
前天装好的Oracle,昨天突然不好用了,从Oracle的错误提示来看,是说TNS:no listener ,估计是某种服务没有启动,打开windows管理工具->服务,一看,有一个Oracle ...
- PagedDataSource数据绑定控件和AspNetPager分页控件结合使用列表分页
1.引用AspNetPager.dll. 2.放置Repeater数据绑定控件. <asp:Repeater ID="Repeater1" runat="serve ...
- JavaScript:理解事件、事件处理函数、钩子函数、回调函数
详情请点击 http://www.jianshu.com/p/a0c580ed3432
- PHP获取网页内容的几种方法
方法1: 用file_get_contents以get方式获取内容 <?php $url='http://www.domain.com/?para=123'; $html= file_get_c ...
- 【Linux】- CentOS查看IP
1.查询命令: ip addr 显示如图: 可以看到ens33没有inet这个属性,那么就没办法通过IP远程连接. 2.设置配置文件: vi /etc/sysconfig/network-script ...
- C#中的反射和扩展方法的运用
前段时间做了一个练手的小项目,采用的是三层架构,也就是Models,IDAL,DAL,BLL 和 Web , 在DAL层中各个类中有一个方法比较常用,那就是 RowToClass ,顾名思义,也就是将 ...
- 配置apt-get告诉下载源
本文转自:http://blog.csdn.net/hyl1718/article/details/7915296 方法: 1.修改源地址: cp /etc/apt/sources.list /etc ...
- C#中整型数据类型
C#中整型数据类型byte是8位的无符号整数,可是它表示的值的范围是0-255才3位啊怎么说是8位啊?谁能帮我解答 全部答案 八位二进制.0000 0000到1111 1111相当于十进制0-25 ...
- c/c++中的关键字(static、const、inline、friend)
static:1.a.c语言中static修饰的局部变量在编译时赋初始值,只赋初始值一次,在函数运行时已有初值,每次调用函数时不用重新赋值,指示保留上次 函 数调用结束时的值. 如果定义局部变量不赋初 ...
- [HAOI2007]分割矩阵 DP+推式子
发现最近好少写博客啊(其实是各种摆去了) 更一点吧 这道题要求最小化均方差,其实凭直觉来说就是要使每个块分的比较均匀一点,但是单单想到想到这些还是不够的, 首先f[i][j][k][l][t]表示以( ...