【题目大意】

小奇和魔法猪要竞选膜钟国的总统。

有 $n$ 个选民,编号为$1...n$,他们中有的人支持小奇,有的人支持魔法猪,还有的人保持中立。

现在你需要把选民分成若干个区间,每个区间的长度在$[l,r]$中。如果一个区间中支持小奇的人比支持魔法猪的人多,那么小奇得一票,一个区间中支持魔法猪的人比支持小奇的人多,那么魔法猪得一票。

小奇想要赢得选举,于是它请你合理地分区间,使得它获得的票数减去魔法猪获得的票数最大。如果你帮它解决了这个问题,它会送你这道题的题解。

$n \leq 10^6$

【题解】

考虑暴力dp,复杂度为$O(n^2)$。

然后考虑优化暴力,每次相当于区间往右移动一格,相当于加入1个数,减去1个数,这个可以用线段树来维护

如果普通写法需要开单调队列,我们可以把下标映射到位置,这样就能执行减去1个数的操作了。

复杂度$O(nlogn)$

# include <vector>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; const int M = 5e5 + , N = 1e6 + , inf = 1e9, SN = * + ; inline int getint() {
int x = , f = ; char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') f = ;
ch = getchar();
}
while(isdigit(ch)) x = (x<<) + (x<<) + ch - '', ch = getchar();
return f ? x : -x;
} int n, L, R, a[N], s[N], f[N], pos[N], idx;
vector<int> v[N + N]; int l[N], r[N]; struct SMT {
int w[N << ];
# define ls (x<<)
# define rs (x<<|)
inline void up(int x) {
w[x] = max(w[ls], w[rs]);
}
inline void build(int x, int l, int r) {
w[x] = -inf;
if(l == r) return ;
int mid = l+r>>;
build(ls, l, mid); build(rs, mid+, r);
}
inline void edt(int x, int l, int r, int pos, int del) {
if(l == r) {
w[x] = del;
return ;
}
int mid = l+r>>;
if(pos <= mid) edt(ls, l, mid, pos, del);
else edt(rs, mid+, r, pos, del);
up(x);
}
inline int query(int x, int l, int r, int L, int R) {
if(L > R) return -inf;
if(L <= l && r <= R) return w[x];
int mid = l+r>>;
if(R <= mid) return query(ls, l, mid, L, R);
else if(L > mid) return query(rs, mid+, r, L, R);
else return max(query(ls, l, mid, L, mid), query(rs, mid+, r, mid+, R));
}
# undef ls
# undef rs
}T; inline void ins(int i) {
// cout << "add " << pos[i] << endl;
T.edt(, , n, pos[i], f[i]);
} inline void del(int i) {
T.edt(, , n, pos[i], -inf);
} int main() {
freopen("election.in", "r", stdin);
freopen("election.out", "w", stdout);
n = getint(), L = getint(), R = getint();
for (int i=; i<=n; ++i) a[i] = getint();
for (int i=; i<=n; ++i) s[i] = s[i-] + a[i];
// for (int i=0; i<=n; ++i) cout << s[i] << ' '; cout << endl; for (int i=; i<=n; ++i) v[s[i] + n].push_back(i);
for (int i=; i<=n+n; ++i) {
int lst = idx;
for (int j=; j<v[i].size(); ++j)
pos[v[i][j]] = idx++;
for (int j=; j<v[i].size(); ++j)
l[v[i][j]] = lst, r[v[i][j]] = idx - ;
}
// for (int i=0; i<=n; ++i) cout << pos[i] << ' ' << l[i] << ' ' << r[i] << endl; cout << endl; f[] = ;
T.build(, , n);
for (int i=; i<=n; ++i) {
if(i - R - >= ) del(i - R - );
if(i - L >= ) ins(i - L);
int ta = T.query(, , n, , l[i]-), tb = T.query(, , n, r[i]+, n), tc = T.query(, , n, l[i], r[i]);
if(ta != -inf) ta ++;
if(tb != -inf) tb --;
// cout << i << "???" << l[i]-1 <<endl;
// cout << i << ' ' << ta << ' ' << tb << ' ' << tc << endl;
f[i] = max(ta, max(tb, tc));
} // }
if(f[n] == -inf) cout << "Impossible";
else cout << f[n];
return ;
}

省队集训 Day5 选举的更多相关文章

  1. FJ省队集训DAY5 T1

    思路:考试的时候打了LCT,自以为能过,没想到只能过80.. 考完一想:lct的做法点数是100W,就算是nlogn也会T. 讲一下lct的做法把:首先如果一条边连接的两个点都在同一个联通块内,那么这 ...

  2. JS省队集训记

    不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...

  3. HN2018省队集训

    HN2018省队集训 Day1 今天的题目来自于雅礼的高二学长\(dy0607\). 压缩包下载 密码: 27n7 流水账 震惊!穿着该校校服竟然在四大名校畅通无阻?霸主地位已定? \(7:10\)从 ...

  4. 2019暑期金华集训 Day5 树上数据结构

    自闭集训 Day5 树上数据结构 前置知识 点分治 边分治 树链剖分 LCT Top Tree LCT时间复杂度 线段树每次查询是严格\(\log n\)的,然而splay维护连续段的时候,如果每次查 ...

  5. Loj #6073.「2017 山东一轮集训 Day5」距离

    Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...

  6. 「2017 山东一轮集训 Day5」苹果树

    「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...

  7. [2018HN省队集训D9T1] circle

    [2018HN省队集训D9T1] circle 题意 给定一个 \(n\) 个点的竞赛图并在其中钦定了 \(k\) 个点, 数据保证删去钦定的 \(k\) 个点后这个图没有环. 问在不删去钦定的这 \ ...

  8. [2018HN省队集训D8T1] 杀毒软件

    [2018HN省队集训D8T1] 杀毒软件 题意 给定一个 \(m\) 个01串的字典以及一个长度为 \(n\) 的 01? 序列. 对这个序列进行 \(q\) 次操作, 修改某个位置的字符情况以及查 ...

  9. [2018HN省队集训D8T3] 水果拼盘

    [2018HN省队集训D8T3] 水果拼盘 题意 给定 \(n\) 个集合, 每个集合包含 \([1,m]\) 中的一些整数, 在这些集合中随机选取 \(k\) 个集合, 求这 \(k\) 个集合的并 ...

随机推荐

  1. Qt MetaObject System详解

    网上的资源比较乱,该文章整理自地址:http://www.xuebuyuan.com/735789.html Qt meta-object系统基于三个方面: 1.QObject提供一个基类,方便派生类 ...

  2. Android基础------SQLite数据库(二)

    1.操作SQLite数据库 1.1 execSQL() 可以执行insert.delete.update和CREATE TABLE之类有更改行为的SQL语句 1.2 rawQuery() 可以执行se ...

  3. Tomcat启动报错ERROR:transport error 202:bind failed:Address already

    昨天在服务器上拷贝了一个tomcat项目,修改了server.xml之后启动居然报错ERROR:transport error 202:bind failed:Address already,应该是远 ...

  4. MySQL常用存储引擎功能与用法详解

    本文实例讲述了MySQL常用存储引擎功能与用法. MySQL存储引擎主要有两大类: 1. 事务安全表:InnoDB.BDB. 2. 非事务安全表:MyISAM.MEMORY.MERGE.EXAMPLE ...

  5. 使用mac电脑,对Github客户端的简单操作1----开源项目

    工作之余自己也会一写一些小的程序项目,由于一直没时间“折腾”开源,之前写博客都是直接粘代码片段,今天看别人写技术博客大都会放出项目Github地址,突然感觉自己有点点out and low,作为一个励 ...

  6. BZOJ 1095 捉迷藏(线段树维护括号序列)

    对于树的一个括号序列,树上两点的距离就是在括号序列中两点之间的括号匹配完之后的括号数... 由此可以得出线段树的做法.. #include<cstdio> #include<iost ...

  7. robot framework连接Oracle错误:ORA-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA

    在使用robot framework的关键字Connect to Database Using Custom params连接Oracle数据库: Connect to Database Using ...

  8. Vika and Segments - CF610D

    Vika has an infinite sheet of squared paper. Initially all squares are white. She introduced a two-d ...

  9. BZOJ2152:聪聪可可——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2152 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一 ...

  10. float,absolute脱离文档流的总结

    dom元素脱离文档流,有如下几种方式: 1. float 脱离文档流,其他dom元素无视他,在其下方布局,但是其未脱离文本流,其他元素的文本会认为他存在,环绕他布局.父元素会无视他,因此无法获取其高度 ...