不难发现,问题即求满足以下条件的$(i,j)$对数:

1.$1\le i<j\le n$且$a_{i}=a_{j}$

2.$\min_{i\le k\le j}y_{k}\ge l$且$\max_{i\le k\le j}y_{k}\le r$

先考虑条件1,枚举$1\le x\le n$,并对满足$a_{i}=x$的$i$个数$cnt$分类讨论:

1.若$cnt\le B$(其中$B$为常数),那么$a_{i}=a_{j}=x$的区间个数和(指对所有这样的$x$)不超过$nB$,暴力预处理出此类区间$y_{i}$的最小值和最大值,即变为一个二维数点的问题

关于这个二维数点,注意到点初始给定且条件只有一边,因此对其中一维使用扫描线处理,那么另外一维即变为支持单点修改和区间查询

由于有$o(nB)$次修改和$o(m)$次查询,为了均摊可以采取多层分块的结构,假设分$t$层,则修改和查询的复杂度分别为$o(nBt)$和$o(mn^{\frac{1}{t}}t)$(取$t=2$即为直接分块,取$t=\log_{2}n$即为线段树)

2.若$cnt>B$,那么这类$x$不超过$\frac{n}{B}$个,对应的$i$将序列划分若干段,并求出每一段$y_{i}$的最大值和最小值,注意到我们仅关心于$l,r$和这些最小值和最大值的关系,因此只有$o(cnt)$个本质不同的位置

由此使用莫队,问题即是要维护被包含的段长度(和和平方和),为了做到线性可以使用回滚莫队+链表,复杂度即$o(cnt\sqrt{m}+m)$,那么总复杂度为$o(n\sqrt{m}+\frac{nm}{B})$

另外,为了去掉其中的$\log$,具体实现是可能要借助基数排序等操作,可以参考代码

取$B=\sqrt{m}$和$t=3$即可,时间复杂度为$o(n\sqrt{m}+mn^{\frac{1}{3}})$,可以通过

(由于常数问题,取$B=4\sqrt{m}$更优,另外为了实现方便代码中取了$t=2$)

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define M 1000005
5 #define ll long long
6 #define pii pair<int,int>
7 #define fi first
8 #define se second
9 struct Data{
10 int l,r,id;
11 bool operator < (const Data &k)const{
12 return ((l<k.l)||(l==k.l)&&(r<k.r));
13 }
14 }Q[M];
15 vector<int>v[N];
16 int n,m,B,x,P[N];
17 ll ans[M];
18 namespace ST{
19 int lg[N],mn[N][20],mx[N][20];
20 void init(){
21 lg[0]=-1;
22 for(int i=1;i<=n;i++)lg[i]=lg[i>>1]+1;
23 for(int i=1;i<=n;i++)mn[i][0]=mx[i][0]=P[i];
24 for(int i=n;i;i--)
25 for(int j=1;j<20;j++){
26 mn[i][j]=min(mn[i][j-1],mn[min(i+(1<<j-1),n)][j-1]);
27 mx[i][j]=max(mx[i][j-1],mx[min(i+(1<<j-1),n)][j-1]);
28 }
29 }
30 int get_min(int l,int r){
31 int m=lg[r-l+1];
32 return min(mn[l][m],mn[r-(1<<m)+1][m]);
33 }
34 int get_max(int l,int r){
35 int m=lg[r-l+1];
36 return max(mx[l][m],mx[r-(1<<m)+1][m]);
37 }
38 }
39 namespace Subtask1{
40 int f[N],sum[N];
41 vector<int>V[N];
42 void update(int k){
43 f[k]++,sum[k>>8]++;
44 }
45 int query(int k){
46 int ans=0;
47 for(int i=0;i<(k>>8);i++)ans+=sum[i];
48 for(int i=((k>>8)<<8);i<=k;i++)ans+=f[i];
49 return ans;
50 }
51 void calc(){
52 for(int i=1;i<=n;i++)
53 if (v[i].size()<=B){
54 for(int x=0;x<v[i].size();x++)
55 for(int y=x+1;y<v[i].size();y++){
56 int mn=ST::get_min(v[i][x],v[i][y]);
57 V[mn].push_back(ST::get_max(v[i][x],v[i][y]));
58 }
59 }
60 for(int i=n,k=m;i;i--){
61 for(int j=0;j<V[i].size();j++)update(V[i][j]);
62 while ((k)&&(Q[k].l==i)){
63 ans[Q[k].id]+=query(Q[k].r);
64 k--;
65 }
66 }
67 }
68 }
69 namespace Subtask2{
70 vector<int>V[N];
71 int sz,cnt,K,l,r,mn[N],mx[N],vis[N],id[N],pos[N],L0[N],L1[N],R0[N],R1[N],L[N],R[N],mnV[N];
72 ll Ans[N];
73 void init(){
74 Ans[0]=0;
75 memset(vis,0,sizeof(vis));
76 memset(L,0,sizeof(L));
77 memset(R,0,sizeof(R));
78 }
79 void check_add(int k){
80 if ((vis[k])&&(vis[k+1])){
81 Ans[0]+=(ll)(k-L[k]+1)*(R[k+1]-k);
82 R[L[k]]=R[k+1],L[R[k+1]]=L[k];
83 }
84 }
85 void check_del(int k){
86 if ((vis[k])&&(vis[k+1])){
87 R[L[k]]=k,L[R[k+1]]=k+1;
88 Ans[0]-=(ll)(k-L[k]+1)*(R[k+1]-k);
89 }
90 }
91 void add(int k){
92 vis[k]=1,L[k]=R[k]=k,Ans[0]++;
93 check_add(k-1),check_add(k);
94 }
95 void del(int k){
96 check_del(k-1),check_del(k);
97 vis[k]=L[k]=R[k]=0,Ans[0]--;
98 }
99 void addl(){
100 if ((L0[l])&&(mx[L0[l]]<=pos[r]))del(L0[l]);
101 if ((L1[l])&&(mx[L1[l]]<=pos[r]))del(L1[l]);
102 l++;
103 }
104 void decl(){
105 l--;
106 if ((L0[l])&&(mx[L0[l]]<=pos[r]))add(L0[l]);
107 if ((L1[l])&&(mx[L1[l]]<=pos[r]))add(L1[l]);
108 }
109 void addr(){
110 r++;
111 if ((R0[r])&&(pos[l]<=mn[R0[r]]))add(R0[r]);
112 if ((R1[r])&&(pos[l]<=mn[R1[r]]))add(R1[r]);
113 }
114 void decr(){
115 if ((R0[r])&&(pos[l]<=mn[R0[r]]))del(R0[r]);
116 if ((R1[r])&&(pos[l]<=mn[R1[r]]))del(R1[r]);
117 r--;
118 }
119 void calc(int k){
120 sz=v[k].size(),cnt=0;
121 memset(vis,0,sizeof(vis));
122 memset(L0,0,sizeof(L0));
123 memset(L1,0,sizeof(L1));
124 memset(R0,0,sizeof(R0));
125 memset(R1,0,sizeof(R1));
126 for(int i=1;i<sz;i++){
127 mn[i]=ST::get_min(v[k][i-1],v[k][i]);
128 mx[i]=ST::get_max(v[k][i-1],v[k][i]);
129 vis[mn[i]]=vis[mx[i]]=1;
130 }
131 for(int i=1;i<=n;i++){
132 if (vis[i])pos[++cnt]=i;
133 id[i]=cnt;
134 }
135 for(int i=1;i<sz;i++){
136 if (!L0[id[mn[i]]])L0[id[mn[i]]]=i;
137 else L1[id[mn[i]]]=i;
138 if (!R0[id[mx[i]]])R0[id[mx[i]]]=i;
139 else R1[id[mx[i]]]=i;
140 }
141 K=max(cnt/B,1);
142 for(int i=0,k=1;i*K<cnt;i++){
143 init();
144 int st=i*K+1,ed=min((i+1)*K,cnt);
145 for(int j=st;j<=cnt;j++){
146 mnV[j]=0x3f3f3f3f;
147 V[j].clear();
148 }
149 while ((k<=m)&&(Q[k].l<=pos[ed])){
150 mnV[id[Q[k].r]]=min(mnV[id[Q[k].r]],id[Q[k].l-1]+1);
151 V[id[Q[k].r]].push_back(k);
152 k++;
153 }
154 for(int j=st;j<ed;j++){
155 l=j+1,r=j,Ans[0]=Ans[j+1]=0;
156 while (mnV[j]<l){
157 decl();
158 Ans[l]=Ans[0];
159 }
160 for(int k=0;k<V[j].size();k++)ans[Q[V[j][k]].id]+=Ans[id[Q[V[j][k]].l-1]+1];
161 while (l<=j)addl();
162 }
163 l=ed,r=ed-1,Ans[0]=0;
164 for(int j=ed;j<=cnt;j++){
165 addr();
166 Ans[l]=Ans[0];
167 while (mnV[j]<l){
168 decl();
169 Ans[l]=Ans[0];
170 }
171 for(int k=0;k<V[j].size();k++)ans[Q[V[j][k]].id]+=Ans[id[Q[V[j][k]].l-1]+1];
172 while (l<ed)addl();
173 Ans[0]=Ans[l];
174 }
175 }
176 }
177 void calc(){
178 for(int i=1;i<=n;i++)
179 if (v[i].size()>B)calc(i);
180 }
181 }
182 int main(){
183 ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
184 cin>>n>>m;
185 B=4*(int)sqrt(m);
186 for(int i=1;i<=n;i++){
187 cin>>x;
188 v[x].push_back(i);
189 }
190 for(int i=1;i<=n;i++)cin>>P[i];
191 for(int i=1;i<=m;i++){
192 cin>>Q[i].l>>Q[i].r;
193 Q[i].id=i;
194 }
195 sort(Q+1,Q+m+1);
196 ST::init();
197 Subtask1::calc();
198 Subtask2::calc();
199 for(int i=1;i<=m;i++)cout<<ans[i]<<'\n';
200 return 0;
201 }

[hdu7099]Just Another Data Structure Problem的更多相关文章

  1. CDOJ 483 Data Structure Problem DFS

    Data Structure Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/proble ...

  2. ZOJ 4009 And Another Data Structure Problem(ZOJ Monthly, March 2018 Problem F,发现循环节 + 线段树 + 永久标记)

    题目链接  ZOJ Monthly, March 2018 Problem F 题意很明确 这个模数很奇妙,在$[0, mod)$的所有数满足任意一个数立方$48$次对$mod$取模之后会回到本身. ...

  3. HDU 6649 Data Structure Problem(凸包+平衡树)

    首先可以证明,点积最值的点对都是都是在凸包上,套用题解的证明:假设里两个点都不在凸包上, 考虑把一个点换成凸包上的点(不动的那个点), 不管你是要点积最大还是最小, 你都可以把那个不动的点跟原点拉一条 ...

  4. [hdu7097]Just a Data Structure Problem

    (四边形不等式的套路题) 对于某一组$a_{i}$,显然可以区间dp,设$f_{l,r}$表示区间$[l,r]$​的答案,则转移即$$f_{l,r}=\begin{cases}0&(l=r)\ ...

  5. [LeetCode] Add and Search Word - Data structure design 添加和查找单词-数据结构设计

    Design a data structure that supports the following two operations: void addWord(word) bool search(w ...

  6. hdu-5929 Basic Data Structure(双端队列+模拟)

    题目链接: Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  7. HDU 5929 Basic Data Structure 模拟

    Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  8. hdu 4217 Data Structure? 树状数组求第K小

    Data Structure? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  9. (*medium)LeetCode 211.Add and Search Word - Data structure design

    Design a data structure that supports the following two operations: void addWord(word) bool search(w ...

随机推荐

  1. Blazor Webassembly多标签页开发

    最近准备用Blazor Webassembly做后台开发要用到多标签页,找了半天发现绝大多数都是Blazor Server的多标签没有Webassembly.没办法只能自己想办法造轮子了. 查了许多资 ...

  2. nginx配置禁止爬虫配置

    1.在配置文件里添加禁止爬虫配置 server { ------ #添加如下内容即可防止爬虫 if ($http_user_agent ~* "qihoobot|Baiduspider|Go ...

  3. 题解 「HDU6403」卡片游戏

    link Description 桌面上摊开着一些卡牌,这是她平时很爱玩的一个游戏.如今卡牌还在,她却不在我身边.不知不觉,我翻开了卡牌,回忆起了当时一起玩卡牌的那段时间. 每张卡牌的正面与反面都各有 ...

  4. Solon 框架如何方便获取每个请求的响应时间?

    经常会有同学问 Solon 怎样才能获取每个请求的响应时间?要求是不需要给每个函数加注解.故此,整理了一下. 不给每个函数加注解,主要有两种方式可以获取请求响应时间: 方式1:基于全局过滤器 Solo ...

  5. 保护模式篇——TLB与CPU缓存

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  6. 【c++ Prime 学习笔记】第2章 变量和基本类型

    2.1 基本内置类型 基本数据类型包含了算术类型(arithmetic type)和空类型(void) 算数类型,包含了字符.整型数.布尔值和浮点数 空类型,不对应具体的值 2.1.1 算术类型 算术 ...

  7. 【二食堂】Beta - Scrum Meeting 10

    Scrum Meeting 10 例会时间:5.25 18:30~18:50 进度情况 组员 当前进度 今日任务 李健 1. 继续文本导入.保存部分的工作issue 2. 完成了技术博客 1. 继续文 ...

  8. [技术博客]使用pylint实现django项目的代码风格检查

    使用pylint实现django项目的代码风格检查 前言 ​ 一个项目大多都是由一个团队来完成,如果没有统一的代码规范,那么每个人的代码的风格必定会有很大的差别.且不说会存在多个人同时开发同一模块的情 ...

  9. Beta阶段第一次会议

    Beta阶段第一次例会 时间:2020.5.16 完成工作 姓名 完成任务 难度 完成度 lm 1.修订网页端信息编辑bug2.修订网页端登录bug(提前完成,相关issue已关闭) 中 100% x ...

  10. 升级MySQL8.0的历险记

    最近忙于Fighting的项目,所以笔耕有些松懈,实为不该. 刚好遇到需要从MySQL5.7.33升级到MySQL8.0.x的需求,于是记录一下整个升级过程,踩坑而过. 背景梗概:本地docker容器 ...