# TPR Spring 2022
{%hackmd @fishhh/style %}
###### tags: `競程題解`,`競程`
Timestamp:2023/01/06
[題目連結](https://codeforces.com/group/H0qY3QmnOW/contest/377730/problem/B)
心得:
其實這題之前有點進去看過了,那時候想不出來。
後來想到,只要控制每一個種類的前綴和就好了! 這樣我就可以知道一個區間內有幾本書ㄌ
但是這是有修改的,所以必須用BIT或線段樹。
於是就建好了!
那再加上一個倍增二分搜,去找最遠需要走的地方即可。
我這題的解法好毒ww
是說官解簡單多ㄌ 直接開STL
ps : 本題的測資有一點點弱?,我下面那個程式有一個bug XD
原本抱持著就傳傳看的心態 然後就AC了 哈哈
```cpp=
#include "iostream"
using namespace std;
int bit[200010][110]={},n;
int sta[200010]={};
int lowbit(int kn){
return kn&-kn;
}
void update(int mk,int pos,int v){
for(;pos<=n;pos+=lowbit(pos)){
bit[pos][mk]+=v;
}
return ;
}
int query(int pos,int m){
int ret=0;
for(;pos;pos-=lowbit(pos)){
ret+=bit[pos][m];
}
return ret;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>sta[i];
update(sta[i],i,1);
}
int t;
cin>>t;
while(t--){
int q,p,c;
cin>>q;
if(q==1){
cin>>p>>c;
update(sta[p],p,-1);
sta[p]=c;
update(c,p,1);
}
else{
cin>>p>>c;
int max_d=0;
bool mi=0;
while(c--){
int st,cnt;
cin>>st>>cnt;
int pw=(1<<14);
int now=p,base=query(p-1,st);
if(cnt==1)
while(pw){
if(now+pw>n){
pw>>=1;
continue;
}
int nxt=now+pw;
int test=query(nxt,st);
test=test-base;
if(test<cnt){
now=nxt;
}
else{
pw>>=1;
}
}
// cout<<now<<" ";
if(now==n){
if(query(n,st)-base<cnt)mi=1;
}
else max_d=max(max_d,now+1);
}
if(mi){
cout<<"-1\n";
}
else{
cout<<max_d<<"\n";
}
}
}
}
```