写了一小时结果被卡常了(笑。

考虑新加入一个数什么时候会产生贡献,或者什么时候不会产生贡献。

发现当一个数的位置与他前一次出现时的位置所构成的区间内假若有一个比它小的数那么就不得不对这个数新进行一次操作而不能共用。

又因为询问一个值域范围内的贡献,所以考虑把这个范围内最大的小于这个数本身的数找出来就行了。

我们令这个数作为这个点的点权。

询问便是询问一个值域范围内的点有多少个点权也满足在这个值域范围内,考虑按照大小重新给所有点定序,值域限制转变为下标限制,这个问题就变成了一个二维数点。差分之后树状数组扫一遍就行了。

考虑怎么预处理一个点的点权,我们可以将所有点从小到大加入线段树并维护区间最大值即可。

复杂度 \(O(n \log n)\)。

下面放出赛后卡过的代码:

#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define lowbit(x) (x&-(x))
using namespace std;
namespace IO{
const int SIZE=1<<21;
static char ibuf[SIZE],obuf[SIZE],*iS,*iT,*oS=obuf,*oT=oS+SIZE-1;
int qr;
char qu[55],c;
bool f;
#define getchar() (IO::iS==IO::iT?(IO::iT=(IO::iS=IO::ibuf)+fread(IO::ibuf,1,IO::SIZE,stdin),(IO::iS==IO::iT?EOF:*IO::iS++)):*IO::iS++)
#define putchar(x) *IO::oS++=x,IO::oS==IO::oT?flush():0
#define flush() fwrite(IO::obuf,1,IO::oS-IO::obuf,stdout),IO::oS=IO::obuf
#define puts(x) IO::Puts(x)
template<typename T>
inline void read(T&x){
for(f=1,c=getchar();c<48||c>57;c=getchar())f^=c=='-';
for(x=0;c<=57&&c>=48;c=getchar()) x=(x<<1)+(x<<3)+(c&15);
x=f?x:-x;
}
template<typename T>
inline void write(T x){
if(!x) putchar(48); if(x<0) putchar('-'),x=-x;
while(x) qu[++qr]=x%10^48,x/=10;
while(qr) putchar(qu[qr--]);
}
inline void Puts(const char*s){
for(int i=0;s[i];i++)
putchar(s[i]);
putchar('\n');
}
struct Flusher_{~Flusher_(){flush();}}io_flusher_;
}
using IO::read;
using IO::write;
const int maxn = 1e6+14;
const int inf = 1e9+7;
int tr[maxn*3+1],tag[maxn*3+1];
inline void pushdown(int cur){
if(tr[cur]==inf) return ;
tr[cur<<1]=min(tr[cur<<1],tag[cur]);
tr[cur<<1|1]=min(tr[cur<<1|1],tag[cur]);
tag[cur<<1]=min(tag[cur<<1],tag[cur]);
tag[cur<<1|1]=min(tag[cur<<1|1],tag[cur]);
tag[cur]=inf;
}
inline void pushup(int cur){
tr[cur]=min(tr[cur<<1],tr[cur<<1|1]);
}
inline void update(int cur,int lt,int rt,int l,int r,int v){
if(lt>rt) return ;
if(l>rt||r<lt) return;
if(l<=lt&&rt<=r){
tr[cur]=min(tr[cur],v);
tag[cur]=min(tag[cur],v);
return ;
}
int mid=(lt+rt)>>1;
pushdown(cur);
update(cur<<1,lt,mid,l,r,v);
update(cur<<1|1,mid+1,rt,l,r,v);
pushup(cur);
}
inline int query(int cur,int lt,int rt,int l,int r){
if(l>rt||r<lt) return inf;
if(l<=lt&&rt<=r) return tr[cur];
int mid=(lt+rt)>>1;
pushdown(cur);
return min(query(cur<<1,lt,mid,l,r),query(cur<<1|1,mid+1,rt,l,r));
}
int Tr[maxn*3+1],Tag[maxn*3+1];
inline void Pushdown(int cur){
if(Tag[cur]==0) return ;
Tr[cur<<1]=max(Tr[cur<<1],Tag[cur]);
Tr[cur<<1|1]=max(Tr[cur<<1|1],Tag[cur]);
Tag[cur<<1]=max(Tag[cur<<1],Tag[cur]);
Tag[cur<<1|1]=max(Tag[cur<<1|1],Tag[cur]);
Tag[cur]=0;
}
inline void Pushup(int cur){
Tr[cur]=max(Tr[cur<<1],Tr[cur<<1|1]);
}
inline void Update(int cur,int lt,int rt,int l,int r,int v){
if(lt>rt) return ;
if(l>rt||r<lt) return;
if(l<=lt&&rt<=r){
Tr[cur]=max(Tr[cur],v);
Tag[cur]=max(Tag[cur],v);
return ;
}
int mid=(lt+rt)>>1;
Pushdown(cur);
Update(cur<<1,lt,mid,l,r,v);
Update(cur<<1|1,mid+1,rt,l,r,v);
Pushup(cur);
}
inline int Query(int cur,int lt,int rt,int l,int r){
if(l>rt||r<lt) return 0;
if(l<=lt&&rt<=r) return Tr[cur];
int mid=(lt+rt)>>1;
Pushdown(cur);
return max(Query(cur<<1,lt,mid,l,r),Query(cur<<1|1,mid+1,rt,l,r));
}
int w[maxn],a[maxn],n,q;
int lst[maxn];
int b[maxn];
int L[maxn],R[maxn];
vector<int> col[maxn];
int cnt;
int answer[maxn];
struct Node{
Node(int L,int R,int ID,int OP){
l=L,r=R,id=ID,op=OP;
}
int l,r,id,op;
};
int tree[maxn];
inline void add(int x){
while(x<=n) tree[x]++,x+=lowbit(x);
}
inline int pre(int x){
int res=0;
while(x>0) res+=tree[x],x-=lowbit(x);
return res;
}
vector<Node> Q[maxn];
int f[maxn];
int main(){
read(n);
read(q);
for(int i=1;i<=n;i++){
read(a[i]);
}
for(int i=1;i<=n;i++){
col[a[i]].push_back(i);
if(lst[a[i]]==0){
w[i]=0;
}
else{
w[i]=-1;
}
lst[a[i]]=i;
}
for(int i=1;i<=n;i++){
int lst=0;
for(int x:col[i]){
if(lst==0) w[x]=0;
else{
w[x]=Query(1,1,n,lst,x);
if(w[x]==0) w[x]=-1;
}
lst=x; }
for(int x:col[i]) Update(1,1,n,x,x,a[x]);
}
for(int i=1;i<=n;i++){
if(col[i].size()==0){
L[i]=n+1;
R[i]=0;
continue;
}
L[i]=cnt+1;
for(int x:col[i]) b[++cnt]=w[x],f[cnt]=x;
R[i]=cnt;
}
for(int i=0;i<(maxn*3);i++) tr[i]=tag[i]=inf;
for(int i=0;i<(maxn*3);i++) Tr[i]=Tag[i]=0;
for(int i=1;i<=n;i++){
update(1,1,n,i,i,L[i]);
Update(1,1,n,i,i,R[i]);
}
for(int i=1;i<=q;i++){
int cl,cr;
read(cl);
read(cr);
int L=query(1,1,n,cl,cr),R=Query(1,1,n,cl,cr);
if(L>R) continue;
Q[L-1].push_back(Node(cl,cr,i,-1));
Q[R].push_back(Node(cl,cr,i,1));
}
int sum=0;
for(int i=1;i<=n;i++){
if(w[f[i]]==0) sum++;
else if(w[f[i]]==-1) sum=sum;
else add(w[f[i]]);
for(Node now:Q[i]){
answer[now.id]+=now.op*(sum+(pre(now.r)-pre(now.l-1)));
}
}
for(int i=1;i<=q;i++) write(answer[i]),putchar('\n');
return 0;
}
/*
10 1
1 6 2 3 2 6 3 10 1 2
3 6
*/

CF1864F 题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. shell 去掉逗号_shell替换和去掉换行符

    用shell处理文件的时候我们常常需要去掉或者加上换行符,name问题就来了怎么才能快速的替换呢? 我们有这样一个文件[root@hxy working]# cat 1 GD200A16C013493 ...

  2. 树莓派 ubuntu server 22.x 连接无线网络

    前言 树莓派系统安装完成后,需要配置网络,由于家里没有多余的网线(网线多少有点乱),所以决定配置无线上网的方式,现在记录下来操作过程 具体操作 sudo nano /etc/netplan/xxxxx ...

  3. Django视图的请求与响应

    1.请求对象 (1)请求方式 print(request.method) (2)请求数据 (3)请求路径 # HttpRequest.path: 表示请求的路径(不含get参数) # HttpRequ ...

  4. 滴滴面试:谈谈你对Netty线程模型的理解?

    Netty 线程模型是指 Netty 框架为了提供高性能.高并发的网络通信,而设计的管理和利用线程的策略和机制. Netty 线程模型被称为 Reactor(响应式)模型/模式,它是基于 NIO 多路 ...

  5. long数据类型跨平台问题

    源代码 #include <iostream> int main() { std::cout << "size of long : " << s ...

  6. 7.17考试总结(NOIP模拟18)[导弹袭击·炼金术士的疑惑·老司机的狂欢]

    问灵十三载,等一不归人. 前言 这回考试全靠 T2 了,别的基本上没分(菜) 总感觉最近进度有亿点快,每天都在补坑,每天都在留坑.... T1 导弹袭击 解题思路 因为这个题的两种长度是不一定的,因此 ...

  7. 算法金 | 你真的完全理解 Logistic 回归算法了吗

    大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 今日 178/10000 1. 引言 吴恩达:机器学习的六个核心算法!, 通透!!十大 ...

  8. uniapp+django登录页面实现

    前后端联动 概述 以一个简单的登录功能为例说明,uni-app的前后端交互 项目地址: 效果图 前端页面开发 项目地址: 后端页面开发 项目地址: 其他参考资料 1.Django项目和uni-app项 ...

  9. 绘图与可视化--matplotlib API入门

    matplotlib API函数都位于matplotlib.pyplot模块中. 本节代码中引入的约定为:import matplotlib.pyplot as plt 另外,numpy库也会用到,约 ...

  10. [经验分享] VPS安装爱快

    前言:本人是作VPN服务端用,配合域名分流,蛮好用.参考1.送一个阿里云腾讯云安装爱快3.X的文档https://bbs.ikuai8.com/thread-97314-1-1.htmlVPS存在的问 ...