谴责这道题发明在线莫队的人,简直就是异端,还好我给在线莫队卡了,支持正义制裁

题意简述

给定序列,设 \(f(l,r,x)\) 表示 \(x\) 在 \([l,r]\) 内的出现次数,对给定 \(l,r,a,b\) 求 \(\sum^{i}_{a\le i\le b} f^{2}(l,r,i)\). (强制在线)

解题思路

既然强制在线了,用不了莫队,那么为什么不用分块做呢.

首先不想分块,先想这题怎么求. 如果我们要求 \(\sum^{i}_{a\le i\le b} f^{2}(l,r,i)\), 我们可以用 \(\sum^{i}_{1\le i\le b} f^{2}(l,r,i) - \sum^{i}_{1\le i\le a-1} f^{2}(l,r,i)\). 这里用的是前缀和的思想,也是很显然的. 那么我们考虑就这样维护一个 \(ans[l][r][k]\) 数组来表示 \(\sum^{i}_{1\le i\le k} f^{2}(l,r,i)\),这样在问的时候不就能直接求了吗.

不过我们这样做有一个小问题,就是三维数组太大,而序列长度也大,会炸,只能处理范围小一点的数据. 所以这个时候分块登场了. 我们可以利用这样的思想拆开区间,来求解整块的数据,剩下的打暴力,最后再把全部子区间答案加一下就好了.

但是两边打暴力也挺慢的,因为我们有不少元素需要处理,会显得效率很低. 所以我们考虑怎么快速计算 \(f(l,r,x)\). 再用一遍前缀和思路,我们利用 \(f(l,r,x)=f(1,r,x)-f(1,l-1,x)\),维护一个数组 \(sum[i][j]\),表示在块 \([1,j]\) 内有多少个 \(i\),这样我们的非整块部分也高效优雅了起来.

接下来考虑怎么在预处理部分把 \(ans[l][r][k]\) 和 \(sum[i][j]\) 全部算出来.

对于 \(ans\),按我们从左向右遍历的思路,很容易发现 \(ans[l][r][k]=ans[l][r-1][k]+f(r,r,k)\). 即为前 \(r-1\) 个块内的答案加上第 \(r\) 块内的答案. 很容易,但注意我们这里的加不是单纯的加. 因为我们定义的时候用的是平方和. 假如我们之前有 \(x\) 个,现在要加上 \(1\) 个,那么应该加上 \((x+1)^{2}-x^{2}=2x+1\). 这是一个需要注意的点.

对于 \(sum\),也很容易发现 \(sum[i][j]=sum[i-1][j]+ f(area\ i)\). 那么我们就可以拿下这道题了.

代码实现

#include<bits/stdc++.h>
using namespace std;
int a[50001],sum[55][20001],//hou many j in fore i area
ans[55][55][20001],//how many [1,k] ans (sqre) from i to j
n,m,q,len,
l[50001],r[50001],
locate[50001],
tot[20001];
void prework(){
len=pow(n,0.666);
l[1]=1;
//work out the location
for(int i=1;i<=n;++i){
locate[i]=i/len+(i%len!=0);
if(i%len==0){
l[locate[i]+1]=i+1;
r[locate[i]]=i;
}
}
//work out the sum : sum[i][j]=sum[i-1][j]+ amount of area i.
for(int i=1;i<=locate[n];++i){
for(int j=1;j<=m;++j){
sum[i][j]=sum[i-1][j];
}
for(int j=l[i];j<=r[i];++j){
sum[i][a[j]]++;
}
}
//work out the ans : ans[i][j][k]=ans[i][j-1][k]+the number of amount k of area j.
//because ans is after sqre, so when add a number, ans from x^2 to (x+1)^2, which need to add 2x+1.
//so tot[] actually store amount of k before each add.
for(int i=1;i<=locate[n];++i){
for(int j=i;j<=locate[n];++j){
for(int k=1;k<=m;++k){
ans[i][j][k]=ans[i][j-1][k];
}
for(int k=l[j];k<=r[j];++k){
ans[i][j][a[k]]+=tot[a[k]]*2+1;
tot[a[k]]++;
}
}
for(int j=l[i];j<=n;++j){
tot[a[j]]&=0;
}
}
for(int i=1;i<=locate[n];++i){
for(int j=i;j<=locate[n];++j){
for(int k=1;k<=m;++k){
ans[i][j][k]+=ans[i][j][k-1];
}
}
}
}
int ask(int nl,int nr,int na,int nb){
//first solve whole area, using ans we worked out : [na,nb] = [1,nb]-[1,na-1]
int res=ans[locate[nl]+1][locate[nr]-1][nb]-ans[locate[nl]+1][locate[nr]-1][na-1];
//work out the other part, the same as we work out the ans
//1.when nl,nr in same area (avoid adding a area two times)
if(locate[nl]==locate[nr]){
for(int i=nl;i<=nr;++i){
if(a[i]>=na&&a[i]<=nb){
res+=tot[a[i]]*2+1;
tot[a[i]]++;
}
}
for(int i=nl;i<=nr;++i){
tot[a[i]]=0;
}
return res;
}
//2.else : left and right
for(int i=nl;i<=r[locate[nl]];++i){
if(a[i]<na||a[i]>nb){
continue;
}
if(!tot[a[i]]){
tot[a[i]]=sum[locate[nr]-1][a[i]]-sum[locate[nl]][a[i]];
}
res+=tot[a[i]]*2+1;
tot[a[i]]++;
}
for(int i=l[locate[nr]];i<=nr;++i){
if(a[i]<na||a[i]>nb){
continue;
}
if(!tot[a[i]]){
tot[a[i]]=sum[locate[nr]-1][a[i]]-sum[locate[nl]][a[i]];
}
res+=tot[a[i]]*2+1;
tot[a[i]]++;
}
//clear tot[]
for(int i=nl;i<=r[locate[nl]];++i){
tot[a[i]]&=0;
}
for(int i=l[locate[nr]];i<=nr;++i){
tot[a[i]]&=0;
}
return res;
}
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
prework();
int o,p,y,u,last=0;
while(q --> 0){
scanf("%d%d%d%d",&o,&p,&y,&u);
o^=last;
p^=last;
y^=last;
u^=last;
last=ask(o,p,y,u);
printf("%d\n",last);
}
}

[TK] 颜色的更多相关文章

  1. Tkinter类之窗口部件类

    Tkinter类之窗口部件类 Tkinter支持15个核心的窗口部件,这个15个核心窗口部件类列表如下:窗口部件及说明:Button:一个简单的按钮,用来执行一个命令或别的操作.Canvas:组织图形 ...

  2. Tkinter 控件详细介绍

    Tkinter 控件详细介绍 1.Button 按钮.类似标签,但提供额外的功能,例如鼠标掠过.按下.释放以及键盘操作/事件 2.Canvas 画布.提供绘图功能(直线.椭圆.多边形.矩形) ;可以包 ...

  3. D3树状图给指定特性的边特别显示颜色

    D3作为前端图形显示的利器,功能之强,对底层技术细节要求相对比较多. 有一点,就是要理解其基本的数据和节点的匹配规则架构,即enter,update和exit原理,我前面的D3基础篇中有介绍过,不明白 ...

  4. tk资料

    Hello World: 让我们开始,作为其他教程的开始, 以"Hello World"程序创建一个文件 叫做Hello.pl  键入下面的内容到它这里: #!/usr/local ...

  5. perl tk说明

    介绍: perl/Tk(也被称为pTK) 是一个模块和代码的收集,尝试 简单的配置Tk 8 部件工具包到强大的词素文文字, 动态内存,I/O, 和面向对象,它是一种解释脚本语言 来制作部件和程序 使用 ...

  6. 用python的TK模块实现猜成语游戏(附源码)

    说明:本游戏使用到的python模块有tkinter,random,hashlib:整个游戏分为四个窗口,一个进入游戏的窗口.一个选关窗口.一个游戏进行窗口和一个游戏结束的窗口. 源码有两个主要的py ...

  7. SVG之颜色、渐变和笔刷的使用

    一.颜色 我们之前使用英文来表示颜色并进行填充,比如: <circle cx="800" cy="120" r="110" strok ...

  8. Python的GUI编程(TK)

    TK在大多数 Unix平台.Windows平台和Macintosh系统都是预装好的,TKinter 模块是 Tk GUI 套件的标准Python接口.可实现Python的GUI编程. Tkinter模 ...

  9. Python3 tkinter基础 Label compound 图片上显示文字 fg字体颜色 font字体大小

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  10. Python3 tkinter基础 Button text,fg 按钮上显示的文字 文字的颜色

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

随机推荐

  1. 记一些java里的数据结构

    0.Vector:过期的,被arraylist取代了 0.1Stack:也不建议使用 1.双向链表LinkedList:由list实现的接口类 2.队列Queue:操作为add remove elem ...

  2. ELK多租户方案

    一.前言 日志分析是目前重要的系统调试和问题排查的重要手段之一,而目前分布式系统由于实例和机器众多,所以构建一套统一日志系统是非常必要的:ELK提供了一整套解决方案,并且都是开源软件,之间互相配合使用 ...

  3. 03 OLED显示屏实现

    目录 前言 一.软件模拟IIC协议 1.开启IIC协议 2.结束IIC协议 3.传输数据 二.OLED的操作 1.传输数据的准备 2.写入命令 3.写入数据 4.初始化函数 5.设置光标 6.显示字符 ...

  4. 【Java】找不到此类异常

    Java.lang.classNotFoundException 找不到此类异常: java.lang.ClassNotFoundException: org.springframework.web. ...

  5. 【Docker】02 上手入门

    环境前提: 软硬件设备:真机 | 服务器 | 虚拟机 操作系统:Linux 协议传输工具:XSHELL等等,直接操作就不用了 网路:必须得有 Docker的安装: 还好在学Linux的时候装了一下,发 ...

  6. 【Mybatis】14 缓存

    1.什么是缓存? - 缓存是指把经常需要读写的数据,保存到一个高速的缓冲区中,这个行为叫缓存 - 也可以是指被保存在高速缓冲区的数据,也叫缓存 2.Mybatis缓存 Mybatis中分为一级缓存和二 ...

  7. Win11、Win10局域网共享文件报错:共享文件夹出现,您的账号已锁定,无法访问

    解决方法,见: https://blog.csdn.net/dengww_/article/details/133887598 解决方法: https://blog.csdn.net/dengww_/ ...

  8. 树莓派3b+ 安装windows10 arm版本的方法及使用体验

    首先,我再网上找到了一个很详细的为树莓派3b安装windows10 arm的教程,实际操作下来发现并不可行. 最后找到了可行的教程: 第3章 将Windows10镜像写入TF卡:https://zhu ...

  9. java获取包下所有的类

    1.背景 给一个Java的包名,获取包名下的所有类.. 根据类上的注解,可以展开很多统一操作的业务 2.直接看代码-spring环境下 package com.qxnw.digit.scm.commo ...

  10. [COCI2013-2014#6] KRUŽNICE 题解

    前言 题目链接:洛谷. 题目分析 显然,手模样例发现答案分为以下几个贡献: 所有圆外面的那个大平面,贡献为 \(1\). 每个圆至少被分成一部分,贡献为 \(n\). 如果有一个圆被"拦腰截 ...