作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿。终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……
具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,
他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬。
你的任务便是告诉小Z,他有多大的概率抽到两只颜色相同的袜子。当然,小Z希望这个概率尽量高,所以他可能会询问多个(L,R)以方便自己选择。
标签:block 练手 lock 答案 tle ast blank efi 编号
无
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。
HH 不断地收集新的贝壳,因此,他的项链变得越来越长。
有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答……因为项链实在是太长了。
于是,他只好求助睿智的你,来解决这个问题。
第一行:一个整数N,表示项链的长度。
第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。
第三行:一个整数M,表示HH 询问的个数。
接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
输出格式:M 行,每行一个整数,依次表示询问对应的答案。
6 1 2 3 4 3 5 3 1 2 3 5 2 6
2 2 4
数据范围:
对于100%的数据,N <= 50000,M <= 200000。
思路o_O:
1)莫队
2)离线+树状数组(然而我并不会(?¯∀¯?))
上代码╰( ̄▽ ̄)╮:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define LL long long using namespace std; const int N = 50010; const int M = 200010; int n,m,k,curL,curR; int answer; int a[N]; LL cnt[M],ans[M]; struct G { int l,r,id,block; bool operator < (const G &qwq)const { if(block==qwq.block) return r < qwq.r; else return block < qwq.block; } }t[M]; void add(int pre) { if(++cnt[a[pre]] == 1) answer++; } void change(int pre) { if(--cnt[a[pre]] == 0) answer--; } void modui() { sort(t+1,t+m+1); curL=1,curR=0; for(int i=1;i<=m;i++) { int L=t[i].l,R=t[i].r; while(curL<L) change(curL++); while(curL>L) add(--curL); while(curR<R) add(++curR); while(curR>R) change(curR--); ans[t[i].id]=answer; } } int main() { scanf("%d",&n); int size=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(int i=1,l,r;i<=m;i++) { scanf("%d%d",&t[i].l,&t[i].r); t[i].id=i; t[i].block=(t[i].l-1)/size+1; } modui(); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }
题目描述
小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求(Sigma)∑(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。
小B请你帮助他回答询问。
第一行,三个整数N、M、K。
第二行,N个整数,表示小B的序列。
接下来的M行,每行两个整数L、R。
输出格式:M行,每行一个整数,其中第i行的整数表示第i个询问的答案。
6 4 3 1 3 2 1 1 3 1 4 2 6 3 5 5 6
6 9 5 2
对于全部的数据,1<=N、M、K<=50000
思路O(∩_∩)O~~:
裸的莫队题...只是可惜我是真的没搞明白为什么可以这样做...然后胡乱敲了一个模板,啪的一下就AC了....
坑点╭(╯^╰)╮:
看样子好像并没有使用到k...
上代码{>~<}:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define LL long long using namespace std; const int N = 50010; int n,m,k,curL,curR; int answer; int a[N]; LL cnt[N],ans[N]; struct G { int l,r,num,block; bool operator < (const G &qwq)const { if(block==qwq.block) return r < qwq.r; else return block < qwq.block; } }t[N]; void change(int pre,bool flag) { if(flag) answer-=(--cnt[a[pre]])<<1|1; else answer+=(cnt[a[pre]]++)<<1|1; } void modui() { sort(t+1,t+m+1); curL=1,curR=0; for(int i=1;i<=m;i++) { int L=t[i].l,R=t[i].r; while(curL<L) change(curL++,1); while(curL>L) change(--curL,0); while(curR<R) change(++curR,0); while(curR>R) change(curR--,1); ans[t[i].num]=answer; } } int main() { scanf("%d%d%d",&n,&m,&k); int size=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1,l,r;i<=m;i++) { scanf("%d%d",&t[i].l,&t[i].r); t[i].num=i; t[i].block=(t[i].l-1)/size+1; } modui(); for(int i=1;i<=m;i++) printf("%lld\n",ans[i]); return 0; }
(___r___)
参考博客:
1.http://foreseeable97.logdown.com/posts/158522-233333
2.http://www.cnblogs.com/hzf-sbit/p/4056874.html
3.http://ydcydcy1.blog.163.com/blog/static/21608904020134411543898/
4.http://vawait.com/manhattanmst/
5.http://blog.csdn.net/huzecong/article/details/8576908
标签:block 练手 lock 答案 tle ast blank efi 编号
原文地址:http://www.cnblogs.com/zxqxwnngztxx/p/7204549.html