当前位置: 首页 > news >正文

P4690 [Ynoi Easy Round 2016] 镜中的昆虫

考虑没有修改就是 HH 的项链,每个位置维护 \(pre_i\) 表示上一个相同数的位置,询问等价于 \(\sum_{i=l}^r [pre_i<l]\),拆成差分形式就是二维偏序可以直接扫描线解决。

单点修改也是简单的,多了修改,相当于多了一个时间维,三维偏序用 cdq 分治解决即可。

而区间修改,这题关键在于其实实际上修改的位置是 \(O(n+m)\) 量级的。

区间推平实际修改的位置是 \(O(L)\),其中 \(L\) 是连续段个数。而每次最多将两个连续段分裂,则分裂出的连续段数为 \(O(m)\),加上原本的 \(n\) 个位置最劣是 \(O(n+m)\) 的。

也就是说对于区间推平同色段数实际上是 \(O(n+m)\) 量级。

也就是说直接 ODT 可以得出每次实际修改的位置与对应的值,然后直接 cdq 分治即可,时间复杂度 \(O((n+m)\log^2 (n+m))\)

可能有点卡空间啊,尽量别用 vector 或是 shrink_to_fit 清下空间就好了。

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define fin(x) freopen(#x".in","r",stdin)
#define fout(x) freopen(#x".out","w",stdout)
#define fr(x) fin(x),fout(x);
#define Fr(x,y) fin(x),fout(y)
#define INPUT(_1,_2,FILE,...) FILE
#define IO(...) INPUT(__VA_ARGS__,Fr,fr)(__VA_ARGS__)
using namespace std;
using namespace __gnu_pbds;
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cfast ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define ll long long
#define ull unsigned long long
#define intz(x,y) memset((x),(y),sizeof((x)))
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
#define tup(x) array<int,(x)>
inline ll read(){ll x=0,f=1;char ch=nc();while(ch<48||ch>57){if(ch=='-')f=-1;ch=nc();}while(ch>=48&&ch<=57)x=x*10+ch-48,ch=nc();return x*f;
}
//void write(int x){cout<<x<<' ';}
//void write(pii x){cout<<"P("<<x.fi<<','<<x.se<<")\n";}
//void write(vector<auto>x){for(auto i:x)write(i);cout<<'\n';}
//void write(auto *a,int l,int r){for(int i=l;i<=r;i++)write(a[i]);cout<<'\n';}
inline ll lowbit(ll x){return x&-x;}
#define pcount(x) __builtin_popcount(x)
inline void cmx(ll &x,ll y){if(y>x)x=y;}
inline void cmn(ll &x,ll y){if(y<x)x=y;}
const int mod=998244353;
ll qp(ll x,int y){ll res=1;for(;y;x=x*x%mod,y>>=1)if(y&1)res=res*x%mod;return res;}
const int N=2e5+5,M=2e6+5;
int a[N],pre[N],lst[N],T,tot,t[N],n,m,ans[N],len;unordered_map<int,int>id;
struct opt{int x,y,v,id;}w[M];
struct odt{#define auto set<node>::iteratorstruct node{int l,r,x;friend bool operator<(node x,node y){return x.l<y.l;}};set<node>t,col[N];auto insert(int l,int r,int x){return col[x].insert(node{l,r}),t.insert({l,r,x}).fi;}void delet(int l,int r,int x){col[x].erase(node{l,r}),t.erase({l,r,x});}auto split(int x){auto it=t.lower_bound(node{x,0,0});if(it!=t.end()&&it->l==x)return it;--it;int l=it->l,r=it->r,v=it->x;delet(l,r,v),insert(l,x-1,v);return insert(x,r,v);}int p(int x){auto it=--t.upper_bound(node{x,0,0});if(it->l==x){auto i=col[it->x].lower_bound(node{x,0,0});return (i==col[it->x].begin()?0:(--i)->r);}else return x-1;}int q[N<<2],_;void upd(int l,int r,int x){auto itr=split(r+1),itl=split(l);_=0;for(auto it=itl;it!=itr;it++){q[++_]=(it->l);auto nxt=col[it->x].upper_bound(*it);if(nxt!=col[it->x].end())q[++_]=(nxt->l);col[it->x].erase(*it);}t.erase(itl,itr),insert(l,r,x);auto nxt=col[x].upper_bound(node{l,r,x});if(nxt!=col[x].end())q[++_]=(nxt->l);for(int I=1,i;I<=_;I++)i=q[I],w[++len]={i,pre[i],-1,0},pre[i]=p(i),w[++len]={i,pre[i],1,0};}#undef auto
}ot;
#define b(x) (x).begin()
inline void upd(int x,int d){++x;for(;x<=n;x+=lowbit(x))t[x]+=d;}
inline int ask(int x){int res=0;++x;for(;x;x-=lowbit(x))res+=t[x];return res;}
inline void clr(int x){++x;for(;x<=n;x+=lowbit(x))t[x]=0;}
bool cmp(opt x,opt y){return x.x<y.x;}
void cdq(int L,int R){if(L==R)return;int mid=L+R>>1;cdq(L,mid),cdq(mid+1,R);for(int l=L,r=mid+1;r<=R;r++){while(l<=mid&&w[l].x<=w[r].x)(w[l].id?0:(upd(w[l].y,w[l].v),1)),++l;if(w[r].id)ans[w[r].id]+=w[r].v*ask(w[r].y);}for(int i=L;i<=mid;i++)if(!w[i].id)clr(w[i].y);inplace_merge(w+L,w+1+mid,w+1+R,cmp);
}
inline void UesugiErii(){cin>>n>>m;for(int i=1,x;i<=n;i++){cin>>x;if(id.find(x)==id.end())id[x]=++T;a[i]=id[x];pre[i]=lst[a[i]],lst[a[i]]=i,w[++len]={i,pre[i],1,0},ot.insert(i,i,a[i]);}for(int i=1;i<=m;i++){int op,l,r,x;cin>>op>>l>>r;if(op==1){cin>>x;if(id.find(x)==id.end())id[x]=++T;x=id[x];ot.upd(l,r,x);}else ++tot,w[++len]={l-1,l-1,-1,tot},w[++len]={r,l-1,1,tot};}cdq(1,len);for(int i=1;i<=tot;i++)cout<<ans[i]<<'\n';
}
signed main(){//IO();cfast;int _=1;//cin>>_;for(;_;_--)UesugiErii();return 0;
}
http://www.jsqmd.com/news/59526/

相关文章:

  • 【MCP系列】飞书MCP启用
  • 2025 年成都殡葬服务公司最新推荐榜,聚焦企业服务品质与人文关怀深度解析成都殡葬 / 成都殡葬一条龙服务公司推荐
  • 易基因:山东大学基础医学院李雷教授团队微量WGBS揭示DNA甲基化调控斑马鱼造血干细胞发育的表观遗传机制|项目文章
  • 2025年中国机床钣金加工企业综合竞争力TOP5排行榜
  • 2025 年支架生产厂家最新推荐榜:聚焦产能与品质,精选五大优质品牌助力工程采购钢结构支架/电力支架/角钢支架/电缆支架/电缆沟支架公司推荐
  • 2025年五大实验室耗材品牌排行榜,芯硅谷实力出众
  • 视频汇聚平台EasyCVR接入设备后发现分辨率与设备端配置不同步的原因排查
  • 2025年中国十工业脚轮厂家推荐:推荐聚氨酯工业脚轮厂家哪家
  • 图片矫正
  • 2025 年桥架源头厂家最新推荐排行榜:覆盖铝合金、充电桩底座、定制、热镀锌等多品类,为工程采购提供权威甄选指南热镀锌/不锈钢/热浸镀锌/耐火/电缆/不锈钢电缆/防火电缆桥架公司推荐
  • 习题解析之:查找数字
  • Ubuntu装机
  • NeurIPS2025公布最佳论文奖
  • 2025年12月,双螺杆颗粒挤出机怎么选?这份推荐榜TOP给你答案
  • 2025年浙江十大留学申请机构推荐:不错的留学申请专业公司、
  • 2025上海健身私教工作室推荐榜——浦东FOR U健身私教馆排名第一
  • 2025无锡特种柜物流服务权威推荐榜单:无锡特种柜渠道/无锡海运特种柜服务商/无锡特种柜运输公司精选
  • 还在找Nano Banana Pro API稳定低价渠道(0.09/张)和官方使用教程?看这一篇就够了
  • shell 变量展开时,变量有无引号保护导致的行为差异
  • 【AI学习-comfyUI学习-文生图-各个部分学习-第一步】 - 详解
  • Linux多线程服务端编程——C++多线程编程
  • 海外数字化营销服务商哪家好?2025一站式出海营销推广服务商宝藏清单,涵盖Facebook、LinkedIn、TikTok、INS、Google多平台
  • 外贸B2B营销获客公司推荐,2025年 Facebook、LinkedIn 领英、TikTok、Google 海外营销推广获客公司精选(12月新版)
  • 精选5 家海外营销推广代运营公司,助力外贸企业通过 Facebook、LinkedIn、TikTok 、INS、Google低成本营销推广高效获客
  • shell 实现高效的单层文件路径匹配方法说明
  • 2025年上海沙盘公司推荐,专业模型制作企业全解析,上海哪家
  • 2025年海外新媒体运营推广公司精选:涵盖海外社交媒体媒体获客、海外短视频运营 (2025年12月新版)
  • 什么是即时通讯软件?最值得推荐的即时通讯软件有哪些?
  • 2025年动力锂电池定制厂家十大排名,中阳机械名列前茅
  • 实用指南:[SEO]网站不收录的原因及解决方法有哪些