2015 CCC - 01 统计数对
源:CNUOJ-0384 http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=354
题目分析:当时拿到这道题第一个想法就是排序后n^2暴力枚举,充分利用好有序这一特性随时“短路”。
read(n);read(m);
int temp; for(int i = ; i < n; i++)
{
read(temp);
if(temp <= m)
{
p[tot].v = temp;
p[tot++].num = i;
}
} sort(p, p + tot); for(int i = ; i < tot - ; i++)
{
for(int j = i + ; j < tot; j++)
{
if(p[i].v + p[j].v > m) break;
else if(p[i].num < p[j].num) ans++;
}
ans %= ;
} printf("%d\n", ans); return ;
算法1
然后很高兴的简单一测试就哭了……为什么答案始终不对呢……
如上图就是一个十分典型的例子(下标为序号),不难发现当我们手算时,我们是算的“2 + 1”,但排完序后计算机执行的是“1 + 2”,序号不符合题意就被砍掉了……
那么怎么解决呢?第一个想法便是优化一下 j 的循环,从头到尾全来一遍,保证不漏解:
read(n);read(m);
int temp; for(int i = ; i < n; i++)
{
read(temp);
if(temp <= m)
{
p[tot].v = temp;
p[tot++].num = i;
}
} sort(p, p + tot); for(int i = ; i < tot; i++)
{
for(int j = ; j < tot; j++)
{
if(i == j) continue;
if(p[i].v + p[j].v > m) break;
else if(p[i].num < p[j].num) ans++;
}
ans %= ;
} printf("%d\n", ans);
算法2
排序是nlogn,枚举是n^2,对于十万的数据量无法吐槽……只能有50分……
好的,接下来我们来分析一下这个算法干了些什么,比如对于3 2 1这个序列:
可以看到,1 -> 2, 2 -> 1 分别别计算过一次,其中红色的一次失败了,蓝色的成功了。(在红色中3 > 2,而在蓝色中是2 < 3满足题意)
也不难得出:每一对数字都被正着计算了一次,反着计算了一次;一次失败,一次成功。
那么:反正判断不判断都是ans++ 一次(仅成功一次,失败的时候不会更新),那为什么要判断呢?
于是,我们编出了下面没有判断编号只判断了大小的程序:
for(int i = ; i < tot - ; i++)
{
for(int j = i + ; j < tot; j++)
{
if(p[i].v + p[j].v > m) break;
ans++;
}
ans %= ;
}
算法3
这个算法常数可以几乎砍掉一半多,但复杂度仍然是n^2的,它的表现……呵呵
进一步的优化就要从查询方法开始了:用十分常见的二分法效果怎么样呢?于是我们终于得到了标程:
#include <iostream> //第一题标程
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std; const int maxn = + ;
int n, m; int p[maxn];
int ans = ; int tot = ; int A[maxn]; void read(int& x)
{
x = ;
char ch = getchar();
int sig = ;
while(!isdigit(ch))
{
if(ch == '-') sig = -;
ch = getchar();
}
while(isdigit(ch))
{
x = x * + ch - '';
ch = getchar();
}
x *= sig;
return ;
} int main()
{
read(n);read(m);
int temp; for(int i = ; i < n; i++)
{
read(temp);
if(temp <= m) p[tot++] = temp;
} sort(p, p + tot); int L, R, M; for(int i = ; i < tot - ; i++)
{
L = i;
R = tot - ; if(p[R] + p[i] <= m)
{
ans += R - i;
continue;
} while(L < R)
{
M = L + R >> ;
//printf("L:%d M:%d R:%d\n", L, M, R);
if(p[i] + p[M] <= m) L = M + ;
else R = M;
} if(L - i > ) ans += L - i - ; //cout << ans << endl;
ans %= ;
} printf("%d\n", ans); return ;
}
从n^2到nlogn是不小的进步,十万的数据专为nlogn而生:
这道题就这样被干掉了……
当然了,其实还可以用treap瞎搞啦:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <ctime>
using namespace std;
const int maxn = + ;
struct Node{
int r, v, s;
Node* ch[];
Node() {}
void maintain(){
s = ch[] -> s + ch[] -> s + ;
return ;
}
}nodes[maxn], *null = &nodes[];
int tot = , n, m, A[maxn];
void read(int& x){
x = ; int sig = ; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') sig = -; ch = getchar(); }
while(isdigit(ch)) x = * x + ch - '', ch = getchar();
x *= sig; return ;
}
void rotate(Node* &o, int d){
Node* k = o -> ch[d ^ ];
o -> ch[d ^ ] = k -> ch[d];
k -> ch[d] = o;
o -> maintain();
k -> maintain();
o = k;
return ;
}
void init(Node* &o, int v){
o -> ch[] = null;
o -> ch[] = null;
o -> s = ;
o -> r = rand();
o -> v = v;
return ;
}
void insert(Node* &o, int v){
if(o == null){
o = &nodes[++ tot];
init(o, v);
}
else{
int d = v < o -> v ? : ;
insert(o -> ch[d], v); //你大爷
if(o -> ch[d] -> r > o -> r) rotate(o, d ^ );
}
o -> maintain();
return ;
}
void remove(Node* &o, int v){
if(o == null) return ;
if(o -> v == v){
if(o -> ch[] == null) o = o -> ch[];
else if(o -> ch[] == null) o = o -> ch[];
else{
int d = o -> ch[] -> r < o -> ch[] -> r ? : ;
rotate(o, d);
remove(o -> ch[d ^ ], v);
}
}
if(o != null) o -> maintain();
return ;
}
/*int find(Node* &o, int v){
if(o == null) return -1;
if(o -> v == v){
if(o -> ch[0] != null) return o -> ch[0] -> s;
else return 1;
}
int d = v < o -> v ? 0 : 1;
return find(o -> ch[d], v);
}//*/
int rank(Node* &o, int v){
if(o == null) return ;
if(o -> v > v) return rank(o -> ch[], v);
else return rank(o -> ch[], v) + o -> ch[] -> s + ;
}
Node* root = null;
long long ans = ;
void Init(){
srand(time());
null -> s = ;
read(n); read(m);
for(int i = ; i < n; i ++){
read(A[i]);
ans += rank(root, m - A[i]);
//printf("%d ", rank(root, m - A[i]));
insert(root, A[i]);
}
return ;
} void print(Node* &o){
if(o == null) return ;
print(o -> ch[]);
printf("%d ", o -> v);
print(o -> ch[]);
return ;
} int main(){
Init();
printf("%lld\n", ans % );
return ;
}
/*
5 100000
1 2 3 4 5
*/
小结:本题一定要好好读条件,仔细分析哪些可以优化。
考点:二分,坑题
2015 CCC - 01 统计数对的更多相关文章
- Cheatsheet: 2015 10.01 ~ 10.31
.NET Publishing your ASP.NET App to Linux in 5 minutes with Docker Integrating AngularJS with ASP.NE ...
- Cheatsheet: 2015 06.01 ~ 06.30
Web The Front-End Optimization Checklist [ASP.NET 5] Production Ready Web Server on Linux. Kestrel + ...
- Murano Weekly Meeting 2015.12.01
Meeting time: 2015.December.1st 1:00~2:00 Chairperson: Nikolay Starodubtsev, from Mirantis Meeting ...
- Murano Weekly Meeting 2015.09.01
Meeting time: 2015.September.1st 1:00~2:00 Chairperson: Nikolay Starodubtsev, from Mirantis Meeting ...
- 使用jquery脚本获取随笔、文章和评论的统计数,自定义显示位置
为了这个问题,花了好些时间去摸索,无奈没有搞定.于是,我就到博问去提问,终于搞定! 在此,非常感谢SeayXu的热心帮助. 1.在需要的位置添加一个标签 <div id="stats_ ...
- Archlinux 2015.07.01 和 Windows7 双系统 安装教程
提前在windows7下给Archlinux预留一个分区,大小最好在20G以上(根据自己硬盘情况分配). 第一步,安装前的准备 从arch官网下载最新的ISO文件archlinux-2015.07.0 ...
- Cheatsheet: 2015 12.01 ~ 12.31
Mobile Setting Up the Development Environment iOS From Scratch With Swift: How to Test an iOS Applic ...
- Cheatsheet: 2015 11.01 ~ 11.30
Golang Roadomatic: Node vs. Go Quick Guide to Golang for Java Developers 3 Go Gotchas Web Choosing a ...
- Cheatsheet: 2015 09.01 ~ 09.30
Web A Guide to Vanilla Ajax Without jQuery Gulp for Beginners A Detailed Walkthrough of ASP.net MVC ...
随机推荐
- IE6与W3C标准的盒模型差异
盒子模型(Box Model)是 CSS 的核心,现代 Web 布局设计简单说就是一堆盒子的排列与嵌套,掌握了盒子模型与它们的摆放控制,会发现再复杂的页面也不过如此,然而,任何美好的事物都有缺憾,盒子 ...
- Java基础知识强化之集合框架笔记41:Set集合之HashSet存储自定义对象并遍历练习
1. HashSet集合存储自定义对象并遍历.如果对象的成员变量值相同即为同一个对象 注意了: 你使用的是HashSet集合,这个集合的底层是哈希表结构. 而哈希表结构底层依赖:hashCode()和 ...
- C# 日期字符串转成javascript日期
1.c# date to js date var csharpStr='/Date(1479694396330)/'; //替换掉非数字 csharpStr=csharpStr.replace(/[^ ...
- instanceof的用法①
public class typeof1{ private String a="zzw"; public void instance(){ if(a instanceof Stri ...
- angularjs hover
<ul class="pdl-15"><li ng-repeat="order in vm.selectOrders" ng-class=&q ...
- Const和ReadOnly
总结一下const和readonly有这么几条区别: const和readonly的值一旦初始化则都不再可以改写: const只能在声明时初始化:readonly既可以在声明时初始化也可以在构造器中初 ...
- 对xml操作
已知有一个XML文件(bookshop.xml)如下: <?xml version="1.0" encoding="gb2312" ?> <b ...
- Oracle AWR报告指标全解析-11011552
1-5 Top 5 Timed EventsWaits : 该等待事件发生的次数, 对于DB CPU此项不可用Times : 该等待事件消耗的总计时间,单位为秒, 对于DB CPU 而言是前台进程所消 ...
- 编码问题导致样式显示在IE中不正常
今天在做项目的时候,遇到样式显示不正常的问题,结果是因为用系统自带的notepad编辑器编辑文件时,编码格式被更改了.我们需要在Notepad++中,将编码格式改成Encode inUTF8 with ...
- JS 导出图片,toDataURL
//输出图片 function exportCanvasAsPNG(id, fileName) { //获取canvas元素 var canvasElement = document.getEleme ...