RT,对于下面的这份代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 500010;
ll readL(){
ll x = 0;
char ch = getchar();
while(!('0'<=ch&&ch<='9')) ch = getchar();
x = ch-'0';
ch = getchar();
while('0'<=ch&&ch<='9'){
x = x*10+ch-'0';
ch = getchar();
}
return x;
}
char readC(){
char ch;
ch = getchar();
while(!('A'<=ch&&ch<='Z')) ch = getchar();
return ch;
}
ll n,m;
ll a[N],res[N],BlockSize,cnt[1000010],tot[1000010];\
ll b[N],c[N];
ll ans = 0;
#define bel(x) (x/BlockSize)
struct UPD{
ll idx,val;
} cha[N];
struct QUS{
ll ql,qr,t,id;
bool operator <(const QUS &b) const{
if(bel(ql)!=bel(b.ql)) return bel(ql)<bel(b.ql);
if(bel(qr)!=bel(b.qr)) return bel(qr)<bel(b.qr);
return t<b.t;
}
} Q[N];
void add(ll val){
tot[cnt[val]]--;
cnt[val]++;
tot[cnt[val]]++;
}
void del(ll val){
tot[cnt[val]]--;
cnt[val]--;
if(cnt[val]<0){//注意这里
cout << val <<endl;
while(1);
}
tot[cnt[val]]++;
}
void tchg(ll cpos,ll qid){
if(cha[cpos].idx>=Q[qid].ql&&cha[cpos].idx<=Q[qid].qr){
del(a[cha[cpos].idx]);
add(cha[cpos].val);
}
swap(a[cha[cpos].idx],cha[cpos].val);
}
int main(){
n = readL();m = readL();
BlockSize = (double)pow(n,0.666);
ll totU = 0,totQ = 0,blen = 0;
for(ll i = 1; i <= n; i++){a[i] = readL();b[++blen] = a[i];}
for(ll i = 1; i <= m; i++){
ll op = readL();
if(op==2){
totU++;
cha[totU].idx = readL();
cha[totU].val = readL();
b[++blen] = cha[totU].val;
} else {
totQ++;
Q[totQ] = (QUS){readL(),readL(),totU,totQ};
}
}
sort(b+1,b+blen+1);
ll len = unique(b+1,b+blen+1)-b-1;
for(ll i = 1; i <= n; i++){
//ll x = a[i];
a[i] = lower_bound(b+1,b+len+1,a[i])-b;
//c[a[i]] = x;
}
for(ll i = 1; i <= totU; i++){
//ll x = cha[i].val;
cha[i].val = lower_bound(b+1,b+len+1,cha[i].val)-b;
//c[a[i]] = x;
}
sort(Q+1,Q+totQ+1);
for(ll i = 1,l = 1,r = 0,cur = 0; i <= totQ; i++){
while(l<Q[i].ql) del(a[l++]);
while(l>Q[i].ql) add(a[--l]);
while(r<Q[i].qr) add(a[++r]);
while(r>Q[i].qr) del(a[r--]);
while(cur<Q[i].t) tchg(++cur,i);
while(cur>Q[i].t) tchg(cur--,i);
for(res[Q[i].id] = 1; tot[res[Q[i].id]] > 0; ++res[Q[i].id]);
}
for(ll i = 1; i <= totQ; i++) printf("%lld\n",res[i]);
return 0;
}
通过 del 里的特判,当一个数的出现次数成为负数时直接让程序 T 掉,这显然是不可能的,可是程序 TLE on #2,但是将莫队移动端点的
while(l<Q[i].ql) del(a[l++]);
while(l>Q[i].ql) add(a[--l]);
while(r<Q[i].qr) add(a[++r]);
while(r>Q[i].qr) del(a[r--]);
改成
while(l>Q[i].ql) add(a[--l]);
while(r<Q[i].qr) add(a[++r]);
while(l<Q[i].ql) del(a[l++]);
while(r>Q[i].qr) del(a[r--]);
就 ac 了,为什么会这样?