刚学分块 1ms 的 MnZn 妹子求计算复杂度
查看原帖
刚学分块 1ms 的 MnZn 妹子求计算复杂度
754311
zhangjiting楼主2024/5/10 16:27

Rt,知道过不了,但是和暴力通过的点一样不愿接受。

顺便问一下 set 常数多少。

#include<bits/stdc++.h>
#define debug(x) cout<<#x<<':'<<x<<endl
using namespace std;
namespace Fread {
const int SIZE = 16;
char buf[SIZE], *S, *T;
inline char getchar() {
    if (S == T) {
        T = (S = buf) + fread(buf, 1, SIZE, stdin);
        if (S == T) return '\n';
    }
    return *S++;
}
}
namespace Fwrite {
const int SIZE = 65536;
char buf[SIZE], *S = buf, *T = buf + SIZE;
inline void flush() {
    fwrite(buf, 1, S - buf, stdout);
    S = buf;
}
inline void putchar(char c) {
    *S++ = c;
    if (S == T) flush();
}
struct NTR {
    ~ NTR() { flush(); }
} ztr;
}
#ifdef ONLINE_JUDGE
    #define getchar Fread :: getchar
    #define putchar Fwrite :: putchar
#endif
namespace Fastio {
struct Reader {
    template<typename T>
    Reader& operator >> (T& x) {
        char c = getchar();
        T f = 1;
        while (c < '0' || c > '9') {
            if (c == '-') f = -1;
            c = getchar();
        }
        x = 0;
        while (c >= '0' && c <= '9') {
            x = (x * 10 + (c - '0'));
            c = getchar();
        }
        x *= f;
        return *this;
    }
    Reader& operator >> (char& c) {
        c = getchar();
        while (c == '\n' || c == ' ') c = getchar();
        return *this;
    }
    Reader& operator >> (char* str) {
        int len = 0;
        char c = getchar();
        while (c == '\n' || c == ' ') c = getchar();
        while (c != '\n' && c != ' ') {
            str[len++] = c;
            c = getchar();
        }
        str[len] = '\0';
        return *this;
    }
    Reader(){}
} cin;
const char endl = '\n';
struct Writer {
    template<typename T>
    Writer& operator << (T x) {
        if (x == 0) { putchar('0'); return *this; }
        if (x < 0) { putchar('-'); x = -x; }
        static int sta[45];
        int top = 0;
        while (x) { sta[++top] = x % 10; x /= 10; }
        while (top) { putchar(sta[top] + '0'); --top; }
        return *this;
    }
    Writer& operator << (char c) {
        putchar(c);
        return *this;
    }
    Writer& operator << (char* str) {
        int cur = 0;
        while (str[cur]) putchar(str[cur++]);
        return *this;
    }
    Writer& operator << (const char* str) {
        int cur = 0;
        while (str[cur]) putchar(str[cur++]);
        return *this;
    }
    Writer(){}
} cout;
}
#define cin Fastio :: cin
#define cout Fastio :: cout
#define endl Fastio :: endl
const int N=2e5+5,M=300;
int n,m,lastans;
int a[N],tmp[N];
int block,tot;
int lt[M],rt[M],belong[N];
int cnt[M][N],f[M][M];
set<int> s;
int mp[N];
map<int,int> ys;
inline void build(){
	for(register int i=1;i<=n;i++) tmp[i]=a[i];
	sort(tmp+1,tmp+n+1);
	int len=unique(tmp+1,tmp+n+1)-tmp-1;
	for(register int i=1;i<=n;i++){
		int tp=a[i];
		a[i]=lower_bound(tmp+1,tmp+len+1,a[i])-tmp;
		ys[a[i]]=tp;
	}
	block=700;
	tot=n/block;
	if(n%block) tot++;
	for(register int i=1;i<=tot;i++){
		lt[i]=(i-1)*block+1;
		rt[i]=i*block;
	}rt[tot]=n;
	for(register int i=1;i<=n;i++) belong[i]=(i-1)/block+1;
	for(register int i=1;i<=n;i++) cnt[belong[i]][a[i]]++;
	for(register int i=1;i<=tot;i++){
		for(register int j=1;j<=n;j++) cnt[i][j]+=cnt[i-1][j];
	}
	for(register int i=1;i<=tot;i++){
		for(register int j=i;j<=tot;j++){
			for(register int k=lt[j];k<=rt[j];k++){
				mp[a[k]]++;
				if(mp[a[k]]%2==1) s.insert(a[k]);
				else if(mp[a[k]]>=2) s.erase(a[k]);
			}
			if(s.size()) f[i][j]=*s.begin();
			else f[i][j]=0;
		}
		memset(mp,0,sizeof(mp));
		s.clear();
	}
}
inline int ask(int x,int y){
	int l=belong[x],r=belong[y];
	if(r-l<=2){
		memset(mp,0,sizeof(mp)),s.clear();
		for(register int i=x;i<=y;i++){
			mp[a[i]]++;
			if(mp[a[i]]%2==1) s.insert(a[i]);
			else if(mp[a[i]]>=2) s.erase(a[i]);
		}
		if(s.size()) return ys[*s.begin()];
		else return 0;
	}
	memset(mp,0,sizeof(mp)),s.clear();
	s.insert(f[l+1][r-1]);
	for(register int i=x;i<=rt[l];i++){
		mp[a[i]]++;
		if((mp[a[i]]+cnt[r-1][a[i]]-cnt[l][a[i]])%2==1) s.insert(a[i]);
		else if((mp[a[i]]+cnt[r-1][a[i]]-cnt[l][a[i]])>=2) s.erase(a[i]);
	}
	for(register int i=lt[r];i<=y;i++){
		mp[a[i]]++;
		if((mp[a[i]]+cnt[r-1][a[i]]-cnt[l][a[i]])%2==1) s.insert(a[i]);
		else if((mp[a[i]]+cnt[r-1][a[i]]-cnt[l][a[i]])>=2) s.erase(a[i]);
	}
	if(s.size()) return ys[*s.begin()];
	else return 0;
}
signed main(){
	cin>>n;
	for(register int i=1;i<=n;i++) cin>>a[i];
	build();
	cin>>m;
	for(register int i=1,l,r;i<=m;i++){
		cin>>l>>r;
		l^=lastans,r^=lastans;
		lastans=ask(l,r);
		cout<<lastans<<endl;
	}
	return 0;
}


块长开 300 是防止 MLE。

2024/5/10 16:27
加载中...