【HOJ2430】【贪心+树状数组】 Counting the algorithms
As most of the ACMers, wy's next target is algorithms, too. wy is clever, so he can learn most of the algorithms quickly. After a short time, he has learned a lot. One day, mostleg asked him that how many he had learned. That was really a hard problem, so wy wanted to change to count other things to distract mostleg's attention. The following problem will tell you what wy counted.
Given 2N integers in a line, in which each integer in the range from 1 to N will appear exactly twice. You job is to choose one integer each time and erase the two of its appearances and get a mark calculated by the differece of there position. For example, if the first 3 is in position 86 and the second 3 is in position 88, you can get 2 marks if you choose to erase 3 at this time. You should notice that after one turn of erasing, integers' positions may change, that is, vacant positions (without integer) in front of non-vacant positions is not allowed.
Input
There are multiply test cases. Each test case contains two lines.
The first line: one integer N(1 <= N <= 100000).
The second line: 2N integers. You can assume that each integer in [1,N] will appear just twice.
Output
One line for each test case, the maximum mark you can get.
Sample Input
3
1 2 3 1 2 3
3
1 2 3 3 2 1
Sample Output
6
9
Hint
We can explain the second sample as this. First, erase 1, you get 6-1=5 marks. Then erase 2, you get 4-1=3 marks. You may notice that in the beginning, the two 2s are at positions 2 and 5, but at this time, they are at positions 1 and 4. At last erase 3, you get 2-1=1 marks. Therefore, in total you get 5+3+1=9 and that is the best strategy.
【分析】
比较水的一道题,根据题意可知,任何两个区间仅为相交或包含的关系。
相交无论先删除哪一个对结果都没有影响,包含当然要先删除外面的那一个,所以从后往前删不会有包含的关系。
具体用树状数组实现就可以了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <map> const int MAXN = * + ;
using namespace std;
struct DATA{
int l, r;
}num[MAXN * ];
int data[MAXN * ];
int C[MAXN * ], cnt[MAXN * ];
int n;
bool get[MAXN * ]; int lowbit(int x){return x&-x;}
void add(int x, int val){
while (x <= * n){
C[x] += val;
x += lowbit(x);
}
return;
}
int sum(int x){
int cnt = ;
while (x > ){
cnt += C[x];
x -= lowbit(x);
}
return cnt;
}
void init(){
C[] = ;
for (int i = ; i <= * n; i++) C[i] = cnt[i] = ;
for (int i = ; i <= * n; i++){
scanf("%d", &data[i]);
if (cnt[data[i]] == ) {num[data[i]].l = i;cnt[data[i]]++;}
else num[data[i]].r = i;
add(i, );
}
long long Ans = ;
memset(get, , sizeof(get));
for (int i = * n; i >= ; i--){
if (get[i] == ) continue;
Ans += sum(i) - sum(num[data[i]].l);
add(i, -);
add(num[data[i]].l, -);
get[i] = get[num[data[i]].l] = ;
}
printf("%lld\n", Ans);
} int main(){
int T = ;
#ifdef LOCAL
freopen("data.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
while (scanf("%d", &n) != EOF){
init();
}
return ;
}
【HOJ2430】【贪心+树状数组】 Counting the algorithms的更多相关文章
- 【bzoj4240】有趣的家庭菜园 贪心+树状数组
题目描述 对家庭菜园有兴趣的JOI君每年在自家的田地中种植一种叫做IOI草的植物.JOI君的田地沿东西方向被划分为N个区域,由西到东标号为1~N.IOI草一共有N株,每个区域种植着一株.在第i个区域种 ...
- 贪心+树状数组维护一下 Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) D
http://codeforces.com/contest/724/problem/D 题目大意:给你一个串,从串中挑选字符,挑选是有条件的,按照这个条件所挑选出来的字符集合sort一定是最后选择当中 ...
- D 洛谷 P3602 Koishi Loves Segments [贪心 树状数组+堆]
题目描述 Koishi喜欢线段. 她的条线段都能表示成数轴上的某个闭区间.Koishi喜欢在把所有线段都放在数轴上,然后数出某些点被多少线段覆盖了. Flandre看她和线段玩得很起开心,就抛给她一个 ...
- [BZOJ4240]有趣的家庭菜园(贪心+树状数组)
最后数列一定是单峰的,问题就是最小化最后的位置序列的逆序对数. 从大到小加数,每次贪心看放左边和右边哪个产生的逆序对数更少,树状数组即可. 由于大数放哪对小数不产生影响,所以正确性显然. 注意相同数之 ...
- [P4064][JXOI2017]加法(贪心+树状数组+堆)
题目描述 可怜有一个长度为 n 的正整数序列 A,但是她觉得 A 中的数字太小了,这让她很不开心. 于是她选择了 m 个区间 [li, ri] 和两个正整数 a, k.她打算从这 m 个区间里选出恰好 ...
- [luoguP2672] 推销员(贪心 + 树状数组 + 优先队列)
传送门 贪心...蒟蒻证明不会... 每一次找最大的即可,找出一次最大的,数列会分为左右两边,左边用stl优先队列维护,右边用树状数组维护.. (线段树超时了....) 代码 #include < ...
- codeforces 1249 D2 Too Many Segments (hard version) 贪心+树状数组
题意 给定n个线段,线段可以相交,第\(i\)个线段覆盖的区间为\([l_i,r_i]\),问最少删除多少个线段让覆盖每个点的线段数量小于等于k. 分析 从左往右扫每个点\(x\),若覆盖点\(x\) ...
- [JZO6401]:Time(贪心+树状数组)
题目描述 小$A$现在有一个长度为$n$的序列$\{x_i\}$,但是小$A$认为这个序列不够优美. 小$A$认为一个序列是优美的,当且仅当存在$k\in [1,n]$,满足:$$x_1\leqsla ...
- UVALive 6911---Double Swords(贪心+树状数组(或集合))
题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
随机推荐
- 硬盘安装RedHat Enterprise Linux 6(转载)
准备条件: (1)RedHat Enterprise Linux 6安装镜像 下载见文章末尾 (2)grub文件(用于引导安装) ...
- 【转】MFC界面更新实现方法
原文网址:http://www.cnblogs.com/skywatcher/p/3572311.html 1.更新窗口 即采用UpdateWindow()函数立即发送WM_PAINT消息更新整个窗口 ...
- python for selenium 数据驱动测试
# -*- coding:utf-8 -*- """ 数据驱动测试,从 csv 文件中读取数据 """ from selenium impo ...
- POJ 1159 Palindrome 最长公共子序列的问题
Description A palindrome is a symmetrical string, that is, a string read identically from left to ri ...
- php将SQL查询结果赋值给变量
2012-03-25 12:12 a786013819 | 分类:数据库DB | 浏览1393次 $sql = "select field1 from pre_common_member_p ...
- Python切割nginx日志_小组_ThinkSAAS
Python切割nginx日志_小组_ThinkSAAS Python切割nginx日志
- 干货!如何正确使用Git Flow
我们已经从SVN 切换到Git很多年了,现在几乎所有的项目都在使用Github管理, 本篇文章讲一下为什么使用Git, 以及如何在团队中正确使用. Git的优点 Git的优点很多,但是这里只列出我认为 ...
- Calendar - SGU 115(日期判断)
这年的开始的第一天是星期 1 代码如下: =============================================================================== ...
- 405. Convert a Number to Hexadecimal
..感觉做的很蠢. 主要就是看负数怎么处理. 举个例子,比如8位: 0111 1111 = 127 1111 1111 = -1 1000 0000 = -128 正常情况1111 1111应该是25 ...
- 圣诞节来了,雪花纷飞的CSS3动画
原文链接:http://www.html5think.com/article/index/id/80