前言
暴力能搞到rk1,为什么要平衡树呢?
update 2021.7.13 现在是rk3。
题目
讲解
纯珂朵莉树做法。如果你还不会,左转模板讲解。
当然只有珂朵莉树的话你会在第 (56) 组数据 ( t TLE) ,不过我们合理利用数据的可观测性,发现输出绝大部分都是 (0),于是猜测它询问的区间很大,修改少,但是其实这个数字根本没有这么多。
所以我们只需要记录一下每个数出现次数,在询问之前判断一下整个序列是否有这么多个数字即可过掉这道题。
代码
//12252024832524
#include <set>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#define TT template<typename T>
#define IT set<node>::iterator
using namespace std;
typedef long long LL;
const int MAXN = 100005;
int n,m,lst;
char opt[2];
struct node
{
int l,r;
mutable int val;
node(int l1,int r1 = -1,int val1 = 0){
l = l1;
r = r1;
val = val1;
}
bool operator < (const node &px)const {
return l < px.l;
}
};
set<node> s;
unordered_map<int,LL> M;
LL Read()
{
LL x = 0,f = 1;char c = getchar();
while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
return x * f;
}
TT void Put1(T x)
{
if(x > 9) Put1(x/10);
putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
if(x < 0) putchar('-'),x = -x;
Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}
IT split(int pos)
{
IT it = s.lower_bound(node(pos));
if(it != s.end() && it->l == pos) return it;
--it;
int l = it->l,r = it->r;
LL dz = it->val;
s.erase(it);
s.insert(node(l,pos-1,dz));
return s.insert(node(pos,r,dz)).first;
}
void merg(int l,int r,int val)
{
M[val] += r-l+1;
IT R = split(r+1),L = split(l);
for(;L != R;++ L)
{
M[L->val] -= (L->r) - (L->l) + 1;
}
R = split(r+1),L = split(l);
s.erase(L,R);
s.insert(node(l,r,val));
}
int Query(int l,int r,int k,int v)
{
IT R = split(r+1),L = split(l);
for(;L != R;++ L)
if(L -> val == v)
{
int ll = L->l,rr = L->r;
if(rr-ll+1 < k) k -= rr-ll+1;
else return ll + k - 1;
}
return 0;
}
int main()
{
// freopen("gold56.in","r",stdin);
// freopen("mine.out","w",stdout);
n = Read(); m = Read();
lst = Read();
int l = 1,r;
for(int i = 2;i <= n;++ i)
{
int val = Read();
if(val != lst) s.insert(node(l,i-1,lst)),M[lst] += i - l,lst = val,l = i;
}
s.insert(node(l,n,lst)); M[lst] += n - l + 1; lst = 0;
while(m --> 0)
{
scanf("%s",opt); l = Read() ^ lst; r = Read() ^ lst;
if(!l) l = 1;
if(opt[0] == 'M') merg(l,r,Read() ^ lst);
else
{
int k = Read() ^ lst,v = Read() ^ lst;
if(M[v] < k) Put(lst = 0,'
');
else Put(lst = Query(l,r,k,v),'
');
}
}
return 0;
}
后记
这道题数据应该是比较随机的,不然肯定过不了。