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

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

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

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

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

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

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

复杂度 \(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. uniapp中OnShow获取缓存

    点击查看代码 function getStorage(key) { return new Promise((resolve, reject) => { uni.getStorage({ key: ...

  2. 国产linux系统(银河麒麟,统信uos)使用 PageOffice 国产版在线动态填充 word 文件

    PageOffice 国产版 :支持信创系统,支持银河麒麟V10和统信UOS,支持X86(intel.兆芯.海光等).ARM(飞腾.鲲鹏.麒麟等)芯片架构. 在实际的Word文档开发中,经常需要自动填 ...

  3. springcloud整合geteway网关服务

    geteway网关 1. 什么是 API 网关(API Gateway)分布式服务架构.微服务架构与 API 网关在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计.开发.测试.部署 ...

  4. wblockCloneObjects 写块克隆的使用

    写块克隆可以把当前数据库的实体写入到另一个dwg文件中去.用法根deepclone类似,不过deepclone只能复制到同一数据库中,而写块克隆是在不同数据库中进行复制的.写块克隆也算是深度克隆,能把 ...

  5. 简单粗暴通过 Binlog 日志来恢复 MySQL 数据

    引言 Binlog 日志的主要作用: 1.增量备份. 2.主从复制. 操作步骤 1.登录 MySQL -> 执行 show variables like '%log_bin%'; 查询 binl ...

  6. HTML——input之密码框

    在 HTML 中,把 <input> 标签的 type 属性设置为 password 可以表示密码框.具体语法格式如下: <input type="password&quo ...

  7. Android OpenMAX(四)OMX Core

    假设我们已经写好了所有的OMX组件,有vdec.venc.adec.aenc,接下来问题来了,我们应该如何管理这些组件呢(创建.销毁)?这一篇文章我们向上一层学习OMX Core提供的标准API. O ...

  8. 莫烦tensorflow学习记录 (6)卷积神经网络 CNN (Convolutional Neural Network)

    卷积 和 神经网络 莫烦大佬的原文章https://mofanpy.com/tutorials/machine-learning/tensorflow/intro-CNN/ 我的理解就是千层饼,鸡蛋烧 ...

  9. ceph deploy部署ceph集群 ceph扩容 rbd存储

    架构拓扑 节点主机 节点IP 节点角色 OS ceph-admin 10.0.0.60 admin deploy mds centos7 ceph-node1 10.0.0.61 mon osd md ...

  10. MySQL学习笔记-事务

    事务 事务:是一组操作的集合,是一个不可分割的工作单位,事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败(当操作中某一步出现异常时,前面已执行的步骤也会失 ...