暴力碾标算
查看原帖
暴力碾标算
91127
_5011_楼主2021/2/4 09:11

RT,O(nm)O(nm) 暴力最大点 1.31s 轻松通过,建议加强数据。

放上暴力代码:

#pragma GCC target("avx2")
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1 << 21], *p1 = buf, *p2 = buf;

inline int qread() {
	register char c = getchar();
	register int x = 0, f = 1;
	while (c < '0' || c > '9') {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		x = (x << 3) + (x << 1) + c - 48;
		c = getchar();
	}
	return x * f;
}

inline unsigned int Abs(const unsigned int& x) {return (x > 0 ? x : -x);}
inline unsigned int Max(const unsigned int& x, const unsigned int& y) {return (x > y ? x : y);}
inline unsigned int Min(const unsigned int& x, const unsigned int& y) {return (x < y ? x : y);}

unsigned int n, a[40005], m, b[40005], cnt[40005], vtop;

inline void Read() {
    n = qread(); m = qread();
    for (int i = 1;i <= n;i++) b[i] = a[i] = qread();
}

inline void Prefix() {
    sort(b + 1, b + n + 1);
    vtop = unique(b + 1, b + n + 1) - b - 1;
    for (int i = 1;i <= n;i++) a[i] = lower_bound(b + 1, b + vtop + 1, a[i]) - b - 1;
	//for (int i = 1;i <= n;i++) printf("%d ", a[i]);
	//puts("");
}

inline void Solve() {
    unsigned int ans = 0;
    for (int i = 1;i <= m;i++) {
        int l = (qread() + ans - 1) % n + 1, r = (qread() + ans - 1) % n + 1;
		if (l > r) swap(l, r);
        memset(cnt, 0, sizeof(int) * vtop);
        int j = l;
        unsigned int ans1 = 0, ans2 = 0, ans3 = 0, ans4 = 0, ans5 = 0, ans6 = 0, ans7 = 0, ans8 = 0;
        for (;j + 8 <= r;j += 8) {
            ans1 = Max(ans1, (++cnt[a[j]] << 16) | (65535 ^ a[j]));
            ans2 = Max(ans2, (++cnt[a[j + 1]] << 16) | (65535 ^ a[j + 1]));
            ans3 = Max(ans3, (++cnt[a[j + 2]] << 16) | (65535 ^ a[j + 2]));
            ans4 = Max(ans4, (++cnt[a[j + 3]] << 16) | (65535 ^ a[j + 3]));
            ans5 = Max(ans5, (++cnt[a[j + 4]] << 16) | (65535 ^ a[j + 4]));
            ans6 = Max(ans6, (++cnt[a[j + 5]] << 16) | (65535 ^ a[j + 5]));
            ans7 = Max(ans7, (++cnt[a[j + 6]] << 16) | (65535 ^ a[j + 6]));
            ans8 = Max(ans8, (++cnt[a[j + 7]] << 16) | (65535 ^ a[j + 7]));
        }
        switch(r - j) {
            case 7: ans8 = Max(ans8, (++cnt[a[j + 7]] << 16) | (65535 ^ a[j + 7]));
            case 6: ans7 = Max(ans7, (++cnt[a[j + 6]] << 16) | (65535 ^ a[j + 6]));
            case 5: ans6 = Max(ans6, (++cnt[a[j + 5]] << 16) | (65535 ^ a[j + 5]));
            case 4: ans5 = Max(ans5, (++cnt[a[j + 4]] << 16) | (65535 ^ a[j + 4]));
            case 3: ans4 = Max(ans4, (++cnt[a[j + 3]] << 16) | (65535 ^ a[j + 3]));
            case 2: ans3 = Max(ans3, (++cnt[a[j + 2]] << 16) | (65535 ^ a[j + 2]));
            case 1: ans2 = Max(ans2, (++cnt[a[j + 1]] << 16) | (65535 ^ a[j + 1]));
            case 0: ans1 = Max(ans1, (++cnt[a[j + 0]] << 16) | (65535 ^ a[j + 0]));
        }
        //for (int i = 1;i <= 5;i++) printf("%d ", cnt[i]);
        //puts("");
        //printf("%u %u %u %u %u %u %u %u\n", ans1, ans2, ans3, ans4, ans5, ans6, ans7, ans8);
        printf("%d\n", ans = b[65536 - (Max(Max(Max(Max(Max(Max(Max(ans1, ans2), ans3), ans4), ans5), ans6), ans7), ans8) & 65535)]);
    }
}

int main() {
    Read();
    Prefix();
    Solve();
    return 0;
}
2021/2/4 09:11
加载中...