P1494 小Z的袜子

终于了解了莫队算法(更专业的名称Square Root Decomposition of Queries)

莫队算法:

  • 一般来说解决静态(实际上也有修改的但复杂度更高)的离线(离线意味着需要知道所有查询)区间查询
  • 我理解的特点是从区间[L,R]到区间[L,R-1],[L+1,R],[L-1,R],[L,R+1]复杂度低
  • 相较与线段树,线段树要求[l,mid],[mid,r]-->[l,r]复杂度较低
  • 莫队时间复杂度为O(nlogn)
  • 采用的是分块处理查询
  • 实现需要注意的点:
    • 为了保持原有查询顺序需要保存原序号,根据原序号存储答案
    • 区间的移动传入的参数是增加的点和删除的点,不要无脑写

关于该题

  • 稍微需要一些数学的变换,记下x,y,z出现的次数分别为a,b,c在区间[l,r],那么概率为C(a,2)+C(b,2)+...C(,2)/C(len,2)
  • 变换 a(a-1)+b(b-1).../len(len-1)=\(\frac{(\sum{a^2}-len)}{ len(len-1)}\)
  • 所以需要维护频度的平方和

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=50005;
inline ll sqr(const ll &x){
return x*x;
}
inline ll gcd(const ll &a,const ll &b){
if(!b) return a;
else return gcd(b,a%b);
}
int belong[maxn];//每个点的分块预处理
ll ans1[maxn],ans2[maxn];//存储i次询问的结果
struct Cmd{
int l,r,id;
friend bool operator <(const Cmd &a,const Cmd &b){
if(belong[a.l]==belong[b.l]) return a.r<b.r;
else return belong[a.l]<belong[b.l];
}
}cmds[maxn];
//存储所有询问,因为要将所有询问存储(离线算法)
//所以有时需要非常毒瘤的读入优化
int n,m,c[maxn],sum[maxn];
//c[]存储n个元素
inline void upd(ll &now,int p,int v){
//更新平方和
now-=sqr(sum[c[p]]);
sum[c[p]]+=v;//c[p]的计数
now+=sqr(sum[c[p]]);
//now应该加上改变后的^2-之前^2
//巧妙的避免了讨论
}
inline void solve(){
int L=1,R=0;//[L,R]为当前维护好的区间
ll now=0;//now为当前区间答案
for(int i=1;i<=m;i++){//莫队主要部分
while(L<cmds[i].l){
upd(now,L,-1);L++;//表示L右移动
}
while(L>cmds[i].l){//加上点L-1
upd(now,L-1,1);L--;
}
while(R<cmds[i].r){//加上点R+1
upd(now,R+1,1);R++;
}
while(R>cmds[i].r){
upd(now,R,-1);R--;
}
if(cmds[i].l==cmds[i].r){
ans1[cmds[i].id]=0;
ans2[cmds[i].id]=1;
continue;
}
ans1[cmds[i].id]=now-(cmds[i].r-cmds[i].l+1);
ans2[cmds[i].id]=(ll)(cmds[i].r-cmds[i].l)*(cmds[i].r-cmds[i].l+1);
//printf("db %d %d %lld %lld %lld\n",cmds[i].l,cmds[i].r,now,ans1[cmds[i].id],ans2[cmds[i].id]);
ll g=gcd(ans1[cmds[i].id],ans2[cmds[i].id]);
ans1[cmds[i].id]/=g;
ans2[cmds[i].id]/=g; } }
int main(){
scanf("%d %d",&n,&m);//n个数,m次询问
int s=sqrt(n);//准备分块
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
belong[i]=((i-1)/s)+1;//每个点分块预处理
}
for(int i=1;i<=m;i++){
scanf("%d %d",&cmds[i].l,&cmds[i].r);
cmds[i].id=i;//需要标号记录原来顺序,因为后面要排序
}
sort(cmds+1,cmds+m+1);//对区间重新排序
solve();
for(int i=1;i<=m;i++){
printf("%lld/%lld\n",ans1[i],ans2[i]);
}
return 0;
}

P1494 [国家集训队]小Z的袜子(luogu)的更多相关文章

  1. P1494 [国家集训队]小Z的袜子

    题目 P1494 [国家集训队]小Z的袜子 解析 在区间\([l,r]\)内, 任选两只袜子,有 \[r-l+1\choose2\] \[=\frac{(r-l+1)!}{2!(r-l-1)!}\] ...

  2. P1494 [国家集训队]小Z的袜子/莫队学习笔记(误

    P1494 [国家集训队]小Z的袜子 题目描述 作为一个生活散漫的人,小\(Z\)每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小\(Z\)再也无法忍受这恼人的找袜子过程,于是他 ...

  3. 洛谷 P1494 [国家集训队] 小Z的袜子

    题目概述: 小Z把N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬. 你的任务 ...

  4. luogu P1494 [国家集训队]小Z的袜子 ( 普 通 )

    题目:    链接:https://www.luogu.org/problemnew/show/P1494 题意:一些袜子排成一排,每个袜子有固定的颜色.                        ...

  5. 【luogu P1494 [国家集训队]小Z的袜子】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1494 #include <cstdio> #include <algorithm> ...

  6. Luogu P1494 [国家集训队]小Z的袜子

    比较简单的莫队题,主要是为了熟练板子. 先考虑固定区间时我们怎么计算,假设区间\([l,r]\)内颜色为\(i\)的袜子有\(cnt_i\)只,那么对于颜色\(i\)来说,凑齐一双的情况个数为: \( ...

  7. P1494 [国家集训队]小Z的袜子(莫队)

    题目链接:https://www.luogu.org/problemnew/show/P1494 题目大意:中文题目 具体思路:计算概率的时候,每一次是区间的移动,每一次移动,记得先将原来的记录的影响 ...

  8. 洛谷 P1494 [国家集训队]小Z的袜子(莫队)

    题目链接:https://www.luogu.com.cn/problem/P1494 一道很经典的莫队模板题,然而每道莫队题的大体轮廓都差不多. 首先莫队是一种基于分块的算法,它的显著特点就是: 能 ...

  9. P1494 [国家集训队]小Z的袜子(莫队算法)

    莫队板子 代码 #include <cstdio> #include <algorithm> #include <cstring> #include <cma ...

随机推荐

  1. Java Spring 两大特色

    0 引言 本文主要描述的是Spring常用的两大特色功能:AOP和IoC容器 1 IoC Spring的IoC:就是常说的“控制反转”,也又叫依赖注入的(DI). 优点:IoC最大的好处就是把对象生成 ...

  2. python文件操作IO

    模式 描述 r 以只读方式打开文件.文件的指针将会放在文件的开头.这是默认模式. rb 以二进制格式打开一个文件用于只读.文件指针将会放在文件的开头.这是默认模式.一般用于非文本文件如图片等. r+ ...

  3. TensorFlow技术解析与实战学习笔记(13)------Mnist识别和卷积神经网络AlexNet

    一.AlexNet:共8层:5个卷积层(卷积+池化).3个全连接层,输出到softmax层,产生分类. 论文中lrn层推荐的参数:depth_radius = 4,bias = 1.0 , alpha ...

  4. python中的全局变量、局部变量、实例变量

    1.全局变量:在模块内,在所有函数.类外面. 2.局部变量:在函数内,在类方法内(未加self修饰的) 3.静态变量:在类内,但不在类方法内.[共同类所有,值改变后,之后所有的实例对象也改变] 4.实 ...

  5. js判断当前移动设备平台

    //js判断当前移动设备平台 var isiOs = false; var isAndroid = false; var isWindowsPhone = false; if(/(iPhone|iPa ...

  6. Ubuntu双系统后时间不对解决方案

    先在ubuntu下更新一下时间,确保时间无误 sudo apt install ntpdate sudo ntpdate time.windows.com 然后将时间更新到硬件上 sudo hwclo ...

  7. Django入门--创建项目及应用

    Django是用于后台处理的web应用框架.用户通过浏览器输入网址,向http服务器发起访问网页的请求,http服务器(Apache/Nginx)接收到用户请求后,把请求发送给web应用框架进行处理, ...

  8. centos solr 集群搭建

    一.什么是 SolrCloud SolrCloud(solr 云)是 Solr 提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时 ...

  9. Java开源框架 iBase4J 搭建笔记

    项目地址:https://gitee.com/iBase4J/iBase4J 搭建步骤:     1.git 代码     2.安装 Zookeeper     3.打包部署 Dubbo Admin ...

  10. Apache 做反向代理服务器

    apache做反向代理服务器 apache代理分为正向代理和反向代理: 1 正向代理: 客户端无法直接访问外部的web,需要在客户端所在的网络内架设一台代理服务器,客户端通过代理服务器访问外部的web ...