CF1864F 题解
写了一小时结果被卡常了(笑。
考虑新加入一个数什么时候会产生贡献,或者什么时候不会产生贡献。
发现当一个数的位置与他前一次出现时的位置所构成的区间内假若有一个比它小的数那么就不得不对这个数新进行一次操作而不能共用。
又因为询问一个值域范围内的贡献,所以考虑把这个范围内最大的小于这个数本身的数找出来就行了。
我们令这个数作为这个点的点权。
询问便是询问一个值域范围内的点有多少个点权也满足在这个值域范围内,考虑按照大小重新给所有点定序,值域限制转变为下标限制,这个问题就变成了一个二维数点。差分之后树状数组扫一遍就行了。
考虑怎么预处理一个点的点权,我们可以将所有点从小到大加入线段树并维护区间最大值即可。
复杂度 \(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 题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- python教程6.2-OS模块random模块
OS模块 random模块
- 防患未然 | AIRIOT城市管廊智能运维解决方案
城市管廊构建复杂,管道内部传感器和附属设备居多,且近年来事故频发,地下空间属性人员进出管理不便,紧急情况应急调度措施有限.传统人工管理模式,运营成本高,且管理水平和质量也无法得到有利保障.因此在管 ...
- rabbit 的下载与安装
因为RabbitMQ是用erlang语言开发的,所以我们在安装RabbitMQ前必须要安装erlang支持. erlang的下载地址:https://www.erlang.org/downloads ...
- Yarp 让系统内调度更灵活 http、https、websocket 反向代理
简介 Yarp 是微软团队开发的一个反向代理组件, 除了常规的 http 和 https 转换通讯,它最大的特点是可定制化,很容易根据特定场景开发出需要的定制代理通道. 详细介绍:https://de ...
- GitHub two-factor authentication开启教程
问题描述 最近登录GitHub个人页面动不动就有一个提示框"...... two-factor authentication will be required for your accoun ...
- SpringBoot系列(一)简介。
概述: Spring Boot 可以简化spring的开发,可以快速创建独立的.产品级的应用程序. 特征: 快速创建独立的 Spring 应用程序 直接嵌入了Tomcat.Jetty或Undertow ...
- 铭瑄B760 ITX 无法睿频 无法跑满
铭瑄B760 ITX 无法睿频 无法跑满 状况: 铭瑄B760 ITX + 12600K,跑分时,大核最高 3.7GHz,电压也不到1V.CPU-Z 跑分才600. 解决方法: 1.关机. 2.长按 ...
- 找不到 .NETFramework,Version=v5.0 的引用程序集。要解决此问题,请为此框架版本安装开发人员工具包(SDK/目标包)或者重新定向应用程序。
找不到 .NETFramework,Version=v5.0 的引用程序集.要解决此问题,请为此框架版本安装开发人员工具包(SDK/目标包)或者重新定向应用程序. visual studio 2019 ...
- sshd服务部署
sshd服务部署 软件安装修改配置文件启动使用 1.搭建所有服务的套路 关闭防火墙和selinux(实验环境都先关闭掉) 配置yum源(公网源或者本地源) 软件安装和检查 了解并修改配置文件 启动服 ...
- -bash: curl: command not found 卸载后重新安装
-bash: curl: command not found rpm -e --nodeps curl yum remove curl rpm -qa|grep curl yum -y install ...