xqqQwQ_ @ 2023-05-17 21:25:43
已经卡了两个小时了,实在蚌埠住了。
明明别的点都跑的很快,就是最后一个点怎么都卡不过去。
求大佬帮忙
#include<bits/stdc++.h>
#define pb push_back
#define pii pair<int, int>
#define mkp make_pair
#define fi first
#define se second
using namespace std;
const int N = 5e4 + 5;
const int MT = 2001;
const int Bit = 31;
const int inf = 1e9;
#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 read()
{
char c=getchar();int x=0;bool f=0;
for(;!isdigit(c);c=getchar())f^=!(c^45);
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
if(f)x=-x;return x;
}
void write(int x) {
if(x <= 9) return putchar(x + '0'), void();
write(x / 10);
putchar(x % 10 + '0');
return;
}
int n, m;
int a[N];
int loc[N], st[N], ed[N];
int maxn[MT][MT], vis[N];
int sss[MT];
int tt[N][32];
vector<pii> pre[MT], suf[MT];
vector<pii> V[N], T, t2;
vector<int> C[N];
int main() {
n = read(), m = read();
for(int i = 1; i <= n; ++i) a[i] = read();
int B = 5 * (int)sqrt(n) + 2, MaxB = 0;
for(int i = 1; i <= n; ++i) {
loc[i] = i / B + 1; MaxB = max(MaxB, loc[i]);
ed[loc[i]] = i;
if(!st[loc[i]]) st[loc[i]] = i;
}
for(int i = 1; i <= MaxB; ++i) {
int su = 0;
for(int j = st[i]; j <= ed[i]; ++j) {
sss[i] |= a[j];
su |= a[j];
if(j == st[i]) {
pre[i].pb(mkp(su, j));
continue;
}
if(su != pre[i].back().fi) pre[i].pb(mkp(su, j));
}
su = 0;
for(int j = ed[i]; j >= st[i]; --j) {
su |= a[j];
if(j == ed[i]) {
suf[i].pb(mkp(su, j));
continue;
}
if(su != suf[i].back().fi) suf[i].pb(mkp(su, j));
}
for(int j = st[i]; j <= ed[i]; ++j) {
for(int k = 0; k < Bit; ++k) if(a[j] & (1 << k)) V[j].pb(mkp(j, k)), vis[k] = 1, C[j].pb(k);
if(j != st[i]) {
for(pii p : V[j - 1]) {
if(vis[p.se]) continue;
V[j].pb(p);
}
}
int su = 0;
for(pii p : V[j]) su |= (1 << p.se), maxn[i][j - p.fi + 1] = max(maxn[i][j - p.fi + 1], su);
for(int k : C[j]) vis[k] = 0;
}
for(int j = 1; j <= ed[i] - st[i] + 2; ++j) maxn[i][j] = max(maxn[i][j], maxn[i][j - 1]);
}
for(int i = 1; i <= m; ++i) {
int opt, x, b;
opt = read(), x = read();
if(opt == 1) {
b = read(); int t = loc[x]; a[x] = b; sss[t] = 0;
int s1 = st[t], s2 = ed[t]; C[x].clear();
for(int k = 0; k < Bit; ++k) if(a[x] & (1 << k)) C[x].pb(k);
int su = 0; pre[t].clear(), suf[t].clear();
for(int j = 0; j <= s2 - s1 + 2; ++j) maxn[t][j] = 0;
for(int j = s1; j <= s2; ++j) {
sss[t] |= a[j];
su |= a[j];
if(j == s1) {
pre[t].pb(mkp(su, j));
continue;
}
if(su != pre[t].back().fi) pre[t].pb(mkp(su, j));
}
su = 0;
for(int j = s2; j >= s1; --j) {
su |= a[j];
if(j == s2) {
suf[t].pb(mkp(su, j));
continue;
}
if(su != suf[t].back().fi) suf[t].pb(mkp(su, j));
}
for(int j = s1; j <= s2; ++j) {
V[j].clear();
int su = 0;
for(int k : C[j]) su |= (1 << k), V[j].pb(mkp(j, k)), vis[k] = 1;
maxn[t][1] = max(maxn[t][1], su);
if(j != s1) {
for(pii p : V[j - 1]) {
if(vis[p.se]) continue;
su |= (1 << p.se); int tmp = j - p.fi + 1;
maxn[t][tmp] = max(maxn[t][tmp], su);
V[j].pb(p);
}
}
for(int k : C[j]) vis[k] = 0;
}
for(int j = 1; j <= s2 - s1 + 1; ++j) maxn[t][j] = max(maxn[t][j], maxn[t][j - 1]);
}
else {
int minn = inf;
for(int t = 1; t <= MaxB; ++t) {
int ll = 1, rr = ed[t] - st[t] + 1, midn, ansn = inf;
while(ll <= rr) {
midn = (ll + rr) >> 1;
if(maxn[t][midn] >= x) ansn = midn, rr = midn - 1;
else ll = midn + 1;
}
minn = min(minn, ansn);
}
T.clear();
for(int t = 1; t <= MaxB; ++t) {
t2.clear();
for(pii p : pre[t]) {
if(T.empty()) break;
while(T.size() && (T.back().fi | p.fi) >= x) {
minn = min(minn, p.se - T[T.size() - 1].se + 1);
T.pop_back();
}
}
int p1 = 0, p2 = 0;
int SS = T.size();
for(int j = 0; j < SS; ++j) T[j].fi |= sss[t];
while(p1 < SS && p2 < suf[t].size()) {
if(T[p1].fi == suf[t][p2].fi) p1++;
else if(T[p1].fi < suf[t][p2].fi) t2.pb(T[p1++]);
else t2.pb(suf[t][p2++]);
}
while(p1 < SS) t2.pb(T[p1++]);
while(p2 < suf[t].size()) t2.pb(suf[t][p2++]);
swap(T, t2);
}
(minn == inf ? puts("-1") : (write(minn), putchar('\n'), 0));
}
}
return 0;
}
by xqqQwQ_ @ 2023-05-17 21:38:13
破案了,最后一个点必须把块长开到
by Miraik @ 2023-05-18 07:59:49
最后一个点基本全是修改。