莫队 学习笔记
阅前声明
题单
为方便,题目链接均在洛谷。
要用桶的时候请尽量不要使用 map
或者 un_map
,会造成不必要的 TLE。
普通莫队
当一个区间问题,可以由
我们先将询问离线下来,并将他们排序。我们先把数列分为若干个块,块长为
对于每一个询问,我们对于上个区间暴力转移到下个区间。可行转移方式之一是先扩大区间再缩小区间。
当
莫队的主体,按上面实现的话,应该是长这样:
int l=1,r=0;
For(i,1,m) {
while(l>q[i].l) upd(a[--l]);
while(r<q[i].r) upd(a[++r]);
while(l<q[i].l) del(a[l++]);
while(r>q[i].r) del(a[r--]);
ans[q[i].idx]=sum;
}
DQUERY - D-query
题意:区间不同数
莫队主体是简单的,于是我们考虑加入和删除。
我们可以开一个桶保存每个数出现的次数:
- 加入时如果保存该数的桶为空,那么答案加
。 - 删除后如果保存该数的桶为空,那么答案减
。 - 然后对桶进行操作即可。
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 200050
int n,m,siz;
map<int,int> cnt;
int a[maxn];
struct node{
int l,r,idx;
bool operator<(const node &x) {
return l/siz==x.l/siz?r<x.r:l<x.l;
}
}q[maxn];
int sum=0;
void upd(int x) {
if(cnt[x]==0) sum++;
cnt[x]++;
}
void del(int x) {
if(cnt[x]==1) sum--;
cnt[x]--;
}
int ans[maxn];
void work() {
in1(n);
siz=sqrt(n);
For(i,1,n) in1(a[i]);
in1(m);
For(i,1,m) in2(q[i].l,q[i].r),q[i].idx=i;
sort(q+1,q+m+1);
int l=q[1].l,r=q[1].l-1;
For(i,1,m) {
while(l>q[i].l) upd(a[--l]);
while(r<q[i].r) upd(a[++r]);
while(l<q[i].l) del(a[l++]);
while(r>q[i].r) del(a[r--]);
ans[q[i].idx]=sum;
}
For(i,1,m) cout<<ans[i]<<'\n';
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
P1494 [国家集训队] 小 Z 的袜子
求区间
中随机选出两个数相等的概率。
简单计数题。
用一个桶
- 加入
前,会对答案产生 的贡献。 - 删除
后,会对答案造成 的贡献。
点击查看代码
#include<bits/stdc++.h>
#define int ll
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 50040
int n,m,siz;
int a[maxn],cnt[maxn];
struct quest{
int l,r,idx;
}q[maxn];
bool cmp(quest a,quest b) {
return a.l/siz==b.l/siz?a.r<b.r:a.l<b.l;
}
pair<int,int> ans[maxn];
int sum=0;
void upd(int x) {sum+=cnt[x]; cnt[x]++; }
void del(int x) {cnt[x]--; sum-=cnt[x]; }
void work() {
in2(n,m);
For(i,1,n) in1(a[i]);
For(i,1,m)
in2(q[i].l,q[i].r),q[i].idx=i;
siz=sqrt(n);
sort(q+1,q+m+1,cmp);
int l=q[1].l,r=q[1].l-1;
For(i,1,m) {
if(q[i].l==q[i].r) {
ans[q[i].idx].first=0;
ans[q[i].idx].second=1;
continue ;
}
while(l>q[i].l) upd(a[--l]);
while(r<q[i].r) upd(a[++r]);
while(l<q[i].l) del(a[l++]);
while(r>q[i].r) del(a[r--]);
ans[q[i].idx].first=sum;
ans[q[i].idx].second=(r-l+1)*(r-l)/2;
if(!ans[q[i].idx].first) ans[q[i].idx].second=1;
}
For(i,1,m) {
int G=__gcd(ans[i].first,ans[i].second);
cout<<ans[i].first/G<<'/'<<ans[i].second/G<<'\n';
}
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
XOR and Favorite Number
询问
中有多少个区间满足区间的异或和为 。
首先我们知道
然后求一段区间
所以答案变为求
我们用一个桶
- 加入
前,会对答案产生 的贡献。 - 删除
后,会对答案产生 的贡献。
点击查看代码
#include<bits/stdc++.h>
#define int ll
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 100050
int n,m,k,siz;
int a[maxn];
int cnt[maxn*20];
ll sum=0;
struct quest{
int l,r,idx;
bool operator<(const quest &x) const{
return l/siz==(x.l/siz)?r<x.r:l<x.l;
}
}q[maxn];
void upd(int x) {
sum+=cnt[x^k];
cnt[x]++;
}
void del(int x) {
cnt[x]--;
sum-=cnt[x^k];
}
int ans[maxn];
void work() {
in3(n,m,k);
siz=sqrt(n);
For(i,1,n) in1(a[i]);
For(i,1,n) a[i]^=a[i-1];
For(i,1,m) {
in2(q[i].l,q[i].r);
q[i].l--;//前缀和导致的
q[i].idx=i;
}
sort(q+1,q+m+1);
int l=1,r=0;
For(i,1,m) {
while(l>q[i].l) upd(a[--l]);
while(r<q[i].r) upd(a[++r]);
while(l<q[i].l) del(a[l++]);
while(r>q[i].r) del(a[r--]);
ans[q[i].idx]=sum;
}
For(i,1,m) cout<<ans[i]<<'\n';
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
P3709 大爷的字符串题
询问区间
众数的出现次数。
我们用一个
那么我们有:
- 每一次插入后,答案
可以更新为 ; - 每一次删除前,如果答案为
且 ,那么 。(因为区间众数次数减一一定会有数,比如说这个 )。
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 200050
int n,m,siz;
int a[maxn],b[maxn];
struct node {
int l,r,idx;
bool operator<(const node &x) const {
if(l/siz!=x.l/siz) return l<x.l;
if((l/siz)&1) return r<x.r;
return r>x.r;
}
}q[maxn];
int cnt[maxn];
int t[maxn];
int mx;
int ans[maxn];
void upd(int x) {
t[cnt[x]]--;
t[++cnt[x]]++;
mx=max(mx,cnt[x]);
}
void del(int x) {
t[cnt[x]]--;
if(cnt[x]==mx&&t[cnt[x]]==0) mx--;
t[--cnt[x]]++;
}
void work() {
in2(n,m);
siz=sqrt(n);
For(i,1,n) in1(a[i]),b[i]=a[i];
sort(b+1,b+n+1);
int len=unique(b+1,b+n+1)-b;
For(i,1,n) a[i]=lower_bound(b+1,b+len+1,a[i])-b;
For(i,1,m) {
in2(q[i].l,q[i].r);
q[i].idx=i;
}
sort(q+1,q+m+1);
int l=1,r=0;
For(i,1,m) {
// cerr<<i<<" qwq\n";
while(l>q[i].l) upd(a[--l]);
while(r<q[i].r) upd(a[++r]);
while(l<q[i].l) del(a[l++]);
while(r>q[i].r) del(a[r--]);
ans[q[i].idx]=mx;
}
For(i,1,m) cout<<-ans[i]<<'\n';
}
signed main() {
// freopen("P3709_2.in","r",stdin);
// freopen("qwq.out","w",stdout);
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
P3245 [HNOI2016] 大数 【未完工】
未完工 qwq。
带修莫队
对于单点修改的题,我们给莫队强行安一个时间的维度,那么一个询问
转移顺序
块长取
那么他应该长这样:
int l=1,r=0,t=0;
For(i,1,tot) {
while(l>q[i].l) upd(a[--l]);
while(r<q[i].r) upd(a[++r]);
while(l<q[i].l) del(a[l++]);
while(r>q[i].r) del(a[r--]);
while(t>q[i].t) {
if(ti[t].first>=q[i].l&&ti[t].first<=q[i].r)
del(a[ti[t].first]),upd(ti[t].second);
swap(a[ti[t].first],ti[t].second); t--;
}
while(t<q[i].t) { t++;
if(ti[t].first>=q[i].l&&ti[t].first<=q[i].r)
del(a[ti[t].first]),upd(ti[t].second);
swap(a[ti[t].first],ti[t].second);
}
ans[q[i].idx]=sum;
}
P1903 [国家集训队] 数颜色 / 维护队列
单点修改区间不同数
和区间不同数大抵相同,略过。
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 200050
int n,m,siz;
int a[maxn];
pair<int,int> ti[maxn]; int top=1,tot;
struct node {
int l,r,t,idx;
bool operator<(const node &x) const {
if(l/siz!=x.l/siz) return l<x.l;
if(r/siz!=x.r/siz) return r<x.r;
return ((r/siz)&1)?t<x.t:t>x.t;
}
}q[maxn];
int cnt[maxn*5],sum;
int ans[maxn];
void upd(int x) {cnt[x]++; if(cnt[x]==1) sum++; }
void del(int x) {if(cnt[x]==1) sum--; cnt[x]--; }
void work() {
cin>>n>>m;
For(i,1,n) cin>>a[i];
For(i,1,m) {
char ch;
cin>>ch;
if(ch=='Q') {
tot++;
cin>>q[tot].l>>q[tot].r;
q[tot].t=top;
q[tot].idx=tot;
} else {
top++;
cin>>ti[top].first>>ti[top].second;
}
}
siz=pow(n,2.0/3)*pow(top,1.0/3)/pow(m,1.0/3);
sort(q+1,q+tot+1);
int l=1,r=0,t=0;
For(i,1,tot) {
while(l>q[i].l) upd(a[--l]);
while(r<q[i].r) upd(a[++r]);
while(l<q[i].l) del(a[l++]);
while(r>q[i].r) del(a[r--]);
while(t>q[i].t) {
if(ti[t].first>=q[i].l&&ti[t].first<=q[i].r)
del(a[ti[t].first]),upd(ti[t].second);
swap(a[ti[t].first],ti[t].second); t--;
}
while(t<q[i].t) { t++;
if(ti[t].first>=q[i].l&&ti[t].first<=q[i].r)
del(a[ti[t].first]),upd(ti[t].second);
swap(a[ti[t].first],ti[t].second);
}
ans[q[i].idx]=sum;
}
For(i,1,tot) cout<<ans[i]<<'\n';
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
CF940F Machine Learning
单点修改,求
中每个数字出现的次数的 。
正常带修莫队。维护每个数出现的次数即可。至于查询,因为出现次数为
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 200050
int n,m,siz;
int a[maxn],b[maxn];
pair<int,int> ti[maxn]; int top=1,tot;
struct node {
int l,r,t,idx;
bool operator<(const node &x) const {
if(l/siz!=x.l/siz) return l<x.l;
if(r/siz!=x.r/siz) return r<x.r;
return ((r/siz)&1)?t<x.t:t>x.t;
}
}q[maxn];
int cnt[maxn*5],sum,T[maxn];
int ans[maxn];
void upd(int x) {T[cnt[x]]--; ++cnt[x]; T[cnt[x]]++; }
void del(int x) {T[cnt[x]]--; --cnt[x]; T[cnt[x]]++; }
void work() {
cin>>n>>m;
For(i,1,n) cin>>a[i],b[i]=a[i];
int ttt=n;
siz=pow(n,2.0/3);
For(i,1,m) {
int opt;
cin>>opt;
if(opt==1) {
tot++;
cin>>q[tot].l>>q[tot].r;
q[tot].t=top;
q[tot].idx=tot;
} else {
top++;
cin>>ti[top].first>>ti[top].second;
b[++ttt]=ti[top].second;
}
}
sort(b+1,b+ttt+1);
int len=unique(b+1,b+ttt+1)-b-1;
For(i,1,n) a[i]=lower_bound(b+1,b+len+1,a[i])-b;
For(i,1,top) ti[i].second=lower_bound(b+1,b+len+1,ti[i].second)-b;
sort(q+1,q+tot+1);
int l=1,r=0,t=0;
For(i,1,tot) {
while(l>q[i].l) upd(a[--l]);
while(r<q[i].r) upd(a[++r]);
while(l<q[i].l) del(a[l++]);
while(r>q[i].r) del(a[r--]);
while(t>q[i].t) {
if(ti[t].first>=q[i].l&&ti[t].first<=q[i].r)
del(a[ti[t].first]),upd(ti[t].second);
swap(a[ti[t].first],ti[t].second); t--;
}
while(t<q[i].t) { t++;
if(ti[t].first>=q[i].l&&ti[t].first<=q[i].r)
del(a[ti[t].first]),upd(ti[t].second);
swap(a[ti[t].first],ti[t].second);
}
sum=1;
For(i,1,n) if(!T[i]) break; else sum=i+1;
ans[q[i].idx]=sum;
}
For(i,1,tot) cout<<ans[i]<<'\n';
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
CF1476G Minimum Difference
莫队好题。
首先我们依旧是记录一个
每一次查询就相当于在
但是因为
时间复杂度
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define fst first
#define scd second
#define dbg puts("IAKIOI")
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 200050
int n,m,siz;
int a[maxn];
// --- Moque ---
struct node {
int l,r,t,k,idx;
bool operator<(const node & x ) const {
if(l/siz!=x.l/siz) return l<x.l;
if(r/siz!=x.r/siz) return r<x.r;
if(t/siz==x.t/siz) {
if((t/siz)&1) return t<x.t;
return t>x.t;
} else return t<x.t;
}
}q[maxn];
int ans[maxn];
pair<int,int> ti[maxn];
int top1,top2;
int cnt[maxn],cntt[maxn];// cnt 记录 i 的出现次数,cntt 记录出现次数为 i 的个数
// --- Moque ---
// --- Block ---
#define maxb 350
int bel[maxn],bsiz;// 每个点属于哪个块,有多少个块
int bl[maxb],br[maxb];// 每个块的最左/右
int bcnt[maxb];// 每个块大小
int c[maxn],topc,reidx[maxn];
// --- Block ---
// --- Moque ---
void upd(int x) {
cntt[cnt[x]]--; bcnt[bel[cnt[x]]]--;
cnt[x]++;
cntt[cnt[x]]++; bcnt[bel[cnt[x]]]++;
}
void del(int x) {
cntt[cnt[x]]--; bcnt[bel[cnt[x]]]--;
cnt[x]--;
cntt[cnt[x]]++; bcnt[bel[cnt[x]]]++;
}
// --- Moque ---
int query(int k) {
topc=0;
For(i,1,bsiz) if(bcnt[i]) {
For(j,bl[i],br[i]) if(cntt[j]) {
c[++topc]=cntt[j];
reidx[topc]=j;
}
}
int ans=1e9;
int i=1,j=0,sum=0;
while(i<=topc) {
while(j<topc&&sum<k) sum+=c[++j];
if(sum>=k) ans=min(ans,reidx[j]-reidx[i]);
else break;
sum-=c[i++];
}
if(ans==1e9) ans=-1;
return ans;
}
void work() {
in2(n,m); siz=pow(n,2.0/3);
bsiz=n/siz;
For(i,1,bsiz) bl[i]=br[i-1]+1,br[i]=br[i-1]+siz;
br[bsiz]=n;
// For(i,1,bsiz) cout<<bl[i]<<' '<<br[i]<<'\n';
For(i,1,bsiz) For(j,bl[i],br[i]) bel[j]=i;
// For(i,1,n) cout<<bel[i]<<' ';
For(i,1,n) in1(a[i]);
For(i,1,m) {
int opt=read();
if(opt==1) {
in3(q[++top1].l,q[top1].r,q[top1].k);
q[top1].idx=top1;
q[top1].t=top2;
} else {
in2(ti[++top2].fst,ti[top2].scd);
}
}
sort(q+1,q+top1+1);
int l=1,r=0,t=0;
For(i,1,top1) {
while(l>q[i].l) upd(a[--l]);
while(r<q[i].r) upd(a[++r]);
while(l<q[i].l) del(a[l++]);
while(r>q[i].r) del(a[r--]);
while(t>q[i].t) {
if(ti[t].fst>=q[i].l&&ti[t].fst<=q[i].r)
del(a[ti[t].fst]),upd(ti[t].scd);
swap(a[ti[t].fst],ti[t].scd); t--;
}
while(t<q[i].t) { t++;
if(ti[t].fst>=q[i].l&&ti[t].fst<=q[i].r)
del(a[ti[t].fst]),upd(ti[t].scd);
swap(a[ti[t].fst],ti[t].scd);
}
ans[q[i].idx]=query(q[i].k);
}
For(i,1,top1) cout<<ans[i]<<'\n';
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
本文来自博客园,作者:coding_goat_qwq,转载请注明原文链接:https://www.cnblogs.com/CodingGoat/p/18620909
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】