关于noip的一道水题.....
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于noip的一道水题.....相关的知识,希望对你有一定的参考价值。
小 T 是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有 n 个矿石,从
到 n 逐一编号,每个矿石都有自己的重量 wi 以及价值 vi。检验矿产的流程是:
1、给定 m个区间[Li,Ri];
2、选出一个参数 W;
3、对于一个区间[L,R ],计算矿石在这个区间上的检验值
Y * 1 , ] , [ i i
R L j ∈ 且 W wj
≥ ,j 是矿石编号
求解那个 ∑1 * ∑v j
j j 不明白没学过这个符号。
noip2011 day2 第2题
∑k
i
其中i表示下界,n表示上界, k从i开始取数,一直取到n,全部加起来。
∑ i 这样表达也可以,表示对i求和,i是变数
例如:
100
∑ i = 1+2+3+4+5+......+100
i=1
200
∑ i = 5+6+7+8+9+......+200
i=5
500
∑ i= 10+11+12+13+14+......+500
i=10
444
∑ Xi = X₁+ X₂+ X₃+ X₄+......+ X₄₄₄
i=1
50
∑ i = 1 + 2 + 3 + 4 +......+ 50 = 1275
i=1
70
∑ X = X + X + X + X +......+ X = 70X
i=1
【没有上下标时,就表示该数或该符号,重复出现】
50
∑ (n+1) = ∑n + ∑1 = 20+21+...+50 +31×1=1116
n=20 参考技术A 。。。这个就是连加符号,念作sigma
比如说∑下面写i=1,上面写n,右边写a[i],就表示i从1循环到n的a[i]之和,即a[1]+a[2]+...+a[n]
类似的有∏是连乘 参考技术B 累加的意思…… 参考技术C 是希腊字母啦 参考技术D 累加
NOIP2007统计数字
题面:
某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。
样例输入:
8 2 4 2 4 5 100 2 100
样例输出:
2 3 4 2 5 1 100 2
数据范围:N <= 200000
这个题因为数据范围很小,所以是一道水题,直接用sort就可以水过。时间复杂度O(nlogn)。
代码:
#include <stdio.h> #include <algorithm> int data[200010]; #define gi(a) do { \ register char ch; while((a = getchar()) > ‘9‘ || a < ‘0‘); for(a -= ‘0‘; (ch = getchar()) >= ‘0‘ && ch <= ‘9‘; a = a*10+ch-‘0‘); } while(0) int main() { register int i, cnt = 0, N; gi(N); for(i = 1; i <= N; i++) gi(data[i]); std::sort(data+1, data+1+N); for(i = 1; i <= N; i++) { cnt++; if(data[i] != data[i+1]) { printf("%d %d\n", data[i], cnt); cnt = 0; } } }
实测144ms
但是如果数据卡sort(这个题数据良心不卡sort),或者N的范围更大,那么我们就要想想更好的算法了。
因为数字是固定不变的,我们首先可以想到一个很常规的算法:
开很多个桶,如果数字a出现了一次,那么桶a就++,最后把桶扫一遍。
但是如果数字太大,那么开很多个桶就会很浪费空间,甚至爆内存。
可以再开一个哈希表优化:
首先扫一遍,把值放进哈希表里,记录++。
然后把哈希表里面记录的数据扫一遍,排序输出。
设不重复的数字为m个,可见m <= n
时间复杂度O(mlogm+n*k),k取决于哈希函数的优劣(人品)
代码如下:
#include <stdio.h> #include <algorithm> #define MAXN 200010 #define gi(a) do { \ register char ch; while((a = getchar()) > ‘9‘ || a < ‘0‘); for(a -= ‘0‘; (ch = getchar()) >= ‘0‘ && ch <= ‘9‘; a = a*10+ch-‘0‘); } while(0) struct number { int num, cnt; }; number vis[MAXN]; number array[MAXN]; inline bool comp(const number &a, const number &b) { return a.num < b.num; } inline void hash(const int &a) { int key = a%MAXN; while(vis[key].cnt && vis[key].num != a) key++; if(vis[key].cnt == 0) vis[key].num = a; vis[key].cnt++; } int main() { int N, tot = 0, a, i, j; gi(N); for(i = 1; i <= N; i++) { gi(a); hash(a); } for(i = 0; i <= MAXN-1; i++) if(vis[i].cnt) array[++tot] = vis[i]; std::sort(array+1, array+tot+1, comp); for(i = 1; i <= tot; i++) printf("%d %d\n", array[i].num, array[i].cnt); return 0; }
实测64ms
(其实就这两个代码速度在所有代码中都是最快的,无论是不是加了优化)
以上是关于关于noip的一道水题.....的主要内容,如果未能解决你的问题,请参考以下文章