Description

给你一下长度为 \(n\) 的序列.

\(a_i=a_j\)

\(l_1 \leqslant i \leqslant r_1\)

\(l_2 \leqslant i \leqslant r_2\)

询问满足条件的 \((i,j)\) 对数.

Sol

分块+前缀和.

非常乱搞啊...

首先分块 \(O(\sqrt{n})\) 一块.

然后在每块里统计块中元素出现次数.

先预处理块与块之间的贡献,然后处理不足一块的.

处理块与块之间的时候,需要前缀和优化一下就可以了,枚举当前块中的元素,复杂度 \(O(n \sqrt{n})\).

处理不足一块的时候有好多细节...自己随便yy一下吧..

总复杂度 \(O(n \sqrt{n})\) .

Code

#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std; typedef long long LL;
const int N = 50005;
const int M = 250;
#define debug(a) cout<<#a<<" = "<<a<<" " int n,m,tmp,q,B;
struct Block{ int a[N],b[M],c; }b[M];
int bl[N],a[N],t1[N],t2[N],t3[N],t4[N];
LL f[M][M]; inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
int GetBl(int x){ if(bl[x] == bl[x-1]) return bl[x]+1;else return bl[x]; }
int GetBr(int x){ if(bl[x] == bl[x+1]) return bl[x]-1;else return bl[x]; }
LL work(int l1,int r1,int l2,int r2){
int L1=GetBl(l1),R1=GetBr(r1),L2=GetBl(l2),R2=GetBr(r2);LL res=0; // debug(l1),debug(r1),debug(l2),debug(r2)<<endl;
// debug(L1),debug(R1),debug(L2),debug(R2)<<endl; //Block and Block
if(L2<=R2) for(int i=L1;i<=R1;i++) res+=f[i][R2]-f[i][L2-1]; // debug(res)<<endl; //count
int c1=0,c2=0;
if(bl[l1] != bl[r1]){
// cout<<"qwq"<<endl;
for(int i=l1;bl[i]<L1;i++) t1[++c1]=a[i],t2[a[i]]++;
for(int i=B*R1+1;i<=r1;i++) t1[++c1]=a[i],t2[a[i]]++;
}else{
if(bl[l1-1]==bl[l1] || bl[r1]==bl[r1+1]) for(int i=l1;i<=r1;i++) t1[++c1]=a[i],t2[a[i]]++;
} // cout<<"----------"<<endl;
// for(int i=1;i<=c1;i++) cout<<t1[i]<<" ";cout<<endl; if(bl[l2]!=bl[r2]){
for(int i=l2;bl[i]<L2;i++) t3[++c2]=a[i],t4[a[i]]++;
for(int i=B*R2+1;i<=r2;i++) t3[++c2]=a[i],t4[a[i]]++;
}else{
if(bl[l2-1]==bl[l2] || bl[r2]==bl[r2+1]) for(int i=l2;i<=r2;i++) t3[++c2]=a[i],t4[a[i]]++;
} // for(int i=1;i<=c2;i++) cout<<t3[i]<<" ";cout<<endl;
// cout<<"----------"<<endl; // leave l1r1 and [l2,r2]
for(int i=1;i<=c1;i++) res+=(L2<=R2 ? b[R2].a[t1[i]]-b[L2-1].a[t1[i]] : 0) + t4[t1[i]];
// leave l2r2 and [L1,R1]
if(L1<=R1) for(int i=1;i<=c2;i++) res+=b[R1].a[t3[i]]-b[L1-1].a[t3[i]]; //clear
for(int i=1;i<=c1;i++) t2[t1[i]]--;
for(int i=1;i<=c2;i++) t4[t3[i]]--; return res;
}
int main(){
// freopen("in.in","r",stdin);
ios::sync_with_stdio(false);
n=in(),m=1,B=sqrt(n)+1;
for(int i=1;i<=n;i++){
if(b[m].c >= B) ++m;
a[i]=in(),bl[i]=m,b[m].b[++b[m].c]=a[i];
// debug(a[i]),debug(b[m].c)<<endl;
} // debug(m)<<endl;
// for(int i=1;i<=m;i++) cout<<b[i].c<<endl; for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++) b[i].a[j]=b[i-1].a[j];
// for(int i=1;i<=n;i++) cout<<bl[i]<<" ";cout<<endl;
for(int j=1;j<=b[i].c;j++) b[i].a[b[i].b[j]]++;
// for(int i=1;i<=n;i++) cout<<bl[i]<<" ";cout<<endl;
} // for(int i=1;i<=n;i++) cout<<bl[i]<<" ";cout<<endl; for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) for(int k=1;k<=b[i].c;k++) f[i][j]+=b[j].a[b[i].b[k]]; // for(int i=1;i<=n;i++) cout<<bl[i]<<" ";cout<<endl; for(q=in();q--;){
int l1=in(),r1=in(),l2=in(),r2=in();
cout<<work(l1,r1,l2,r2)<<endl;
}return 0;
}

  

Codeforces Gym 101138 D. Strange Queries的更多相关文章

  1. 【 Gym - 101138D 】Strange Queries (莫队算法)

    BUPT2017 wintertraining(15) #4B Gym - 101138D 题意 a数组大小为n.(1 ≤ n ≤ 50 000) (1 ≤ q ≤ 50 000)(1 ≤ ai ≤  ...

  2. Codeforces Gym 101138 G. LCM-er

    Description 在 \([a,b]\) 之间选择 \(n\) 个数 (可以重复) ,使这 \(n\) 个数的最小公倍数能被 \(x\) 整除,对 \(10^9+7\) 取膜. \(1\leqs ...

  3. Codeforces Gym 101252D&&floyd判圈算法学习笔记

    一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...

  4. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

  5. Codeforces Gym 101623A - 动态规划

    题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...

  6. 【Codeforces Gym 100725K】Key Insertion

    Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...

  7. Codeforces gym 101343 J.Husam and the Broken Present 2【状压dp】

     2017 JUST Programming Contest 2.0 题目链接:Codeforces gym 101343 J.Husam and the Broken Present 2 J. Hu ...

  8. codeforces gym 100553I

    codeforces gym 100553I solution 令a[i]表示位置i的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...

  9. Codeforces 718A Efim and Strange Grade 程序分析

    Codeforces 718A Efim and Strange Grade 程序分析 jerry的程序 using namespace std; typedef long long ll; stri ...

随机推荐

  1. Oracle 的表备份的方法

    1.直接备份(防止误操作后数据库表不能恢复) create table new_table as select * from old_table; 2.创建表头,然后插入列(繁琐的做法) create ...

  2. 服务器后台TCP连接存活问题

    0. 背景 公司的服务器后台部署在某一个地方,接入的是用户的APP,而该地方的网络信号较差,导致了服务器后台在运行一段时间后用户无法接入,那边的同事反馈使用netstat查看系统,存在较多的TCP连接 ...

  3. HTML5 web Form表单验证实例

    HTML5 web Form 的开发实例! index.html <!DOCTYPE html> <html> <head> <meta charset=&q ...

  4. Multiple actions were found that match the request Web API

    在WebAPI工程入口不对外公开的接口不能使用public. [HttpPost] public string PostRequest([FromBody] Model model) { /// } ...

  5. 彻底解决Eclipse自动补全变量名及变量名后面追加类型名

    彻底解决Eclipse自动补全变量名问题的方法步骤 发布于 2014-11-04 14:53   已被阅读 31613159 次 大家使用eclipse或者MyEclipse敲代码的时候,是不是都被这 ...

  6. DNS域传送漏洞利用

    DNS区域传送(DNS zone transfer)指的是一台备用服务器使用来自主服务器的数据刷新自己的域(zone)数据库.这为运行中的DNS服务提供了一定的冗余度,其目的是为了防止主的域名服务器因 ...

  7. css书写规则总结

    1. JavaScript钩子使用的class不能是css class,要加j或j-前缀 2. 选择器 2.1 css选择器尽量简短,层级要少,最好是1-2层 例如:.nav{} 优于 ul.nav{ ...

  8. Jetty多Connector

    有时候想要启动两个端口,或者通过一个Jetty server提供多个不同服务,比如说使用8080来指定默认访问端口,使用8433指定https访问端口等等,此时就可以通过创建多个Connector来解 ...

  9. java 的 AccessController.doPrivileged使用

    AccessController.doPrivileged意思是这个是特别的,不用做权限检查. 在什么地方会用到呢:加入1.jar中有类可以读取一个文件,现在我们要使用1.jar去做这个事情.但是我们 ...

  10. mysql支持跨表delete删除多表记录

    前几天写了Mysql跨表更新的一篇总结,今天我们看下跨表删除. 在Mysql4.0之后,mysql开始支持跨表delete. Mysql可以在一个sql语句中同时删除多表记录,也可以根据多个表之间的关 ...