减半警报器

include<bits/stdc++.h>

define pi pair<ll, int>

define mp make_pair

using namespace std;
using ll = long long;

const int N = 1e5 + 7;
int i, j, k, n, m, x, L, iq, o, id[N];
vector d[N], ans;
bitset pr;
ll v[N], y, cnt[N], mx[N];

ll sz(int k) {
ll s = 0;
for(int x : d[k]) s += cnt[x];
return s;
}

ll read(){
ll ans=0,flag=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')flag=-1;ch=getchar();}
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans*flag;
}

struct pq {
ll x; int y, z;// x -> 警报值,y -> 加入时的 id(用于懒惰删除),z -> 加入的询问
bool operator < (const pq&X) const {
return x != X.x ? x > X.x : (y != X.y ? y > X.y : z > X.z);
}
};
priority_queue q[N];

void chk(int k) {
while(q[k].size()) {
while(q[k].size() && q[k].top().y != mx[q[k].top().z]) q[k].pop();
if(!q[k].size() || q[k].top().x > cnt[k]) return;
pq u = q[k].top(); q[k].pop();
ll s = sz(id[u.z]);
++mx[u.z];//mx -> 最后加入的 id
if(s < v[u.z]) {
u.x = v[u.z] - s;
ll ss = (ll)ceil(1.0 * u.x / d[id[u.z]].size());
for(int x : d[id[u.z]]) {
q[x].push({ss + cnt[x], mx[u.z], u.z});
}
} else ans.push_back(u.z);
}
}

int main() {
n = read(), m = read();
for(i = 2; i < N; i++) if(!pr[i])
for(j = i; j < N; j += i) pr[j] = 1, d[j].push_back(i);
while(m--) {
o = read(), x = read(), y = read();
y ^= L;
if(o) {
v[++iq] = y + sz(x); id[iq] = x; mx[iq] = 1;
ll s = (ll)ceil(1.0 * y / d[x].size());
if(!y) {
ans.push_back(iq);
continue;
}
for(int k : d[x]) q[k].push({s + cnt[k], 1, iq});
} else {
for(int k : d[x]) cnt[k] += y;
for(int k : d[x]) chk(k);
printf("%d ", L = ans.size());
sort(ans.begin(), ans.end());
for(int k : ans) printf("%d ", k); puts("");
ans.clear();
}
}
return 0;
}

posted @ 2024-09-20 20:48  gzyqwq  阅读(43)  评论(0)    收藏  举报