社区讨论
求帮忙看下为什么RE
P5610[Ynoi2013] 大学参与者 12已保存回复 15
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 15 条
- 当前快照
- 1 份
- 快照标识符
- @loct4av8
- 此快照首次捕获于
- 2023/10/30 19:18 2 年前
- 此快照最后确认于
- 2023/11/05 05:58 2 年前
受题解区的影响,用了开始指针代替 vector
CPP#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
//#define int long long
int rd()
{
int x=0 ; char c = getchar();
while(c<'0' || c>'9') c=getchar();
while(c>='0' && c<='9') x=x*10+c-'0', c=getchar();
return x;
}
const int N = 5e5+23, SZ = 7000000 + 233;
int n,m,w, a[1000000+3];
int c[N], d[N], n_[N]; // c[i] 最终会是初始 a[i] 内 i 的倍数的个数, n_ 用来填数
int fa[SZ], s[SZ]; // fa是并查集, s是存储所有倍数所在位置的
ll t[1000000+3];// 树状数组
void add(int x, ll v) {
for(;x<=n;x+=x&(-x)) t[x] += v;
}
ll ask(int x) {
ll res = 0ll;
for(;x;x-=x&(-x)) res += t[x];
return res;
}
int fid(int *fa_, int x) {return x==fa_[x] ? x : fa_[x]=fid(fa_, fa_[x]);}
void div(int l,int r,int x)
{
int *fa_ = fa+d[x], *s_ = s+d[x];
int D = c[x];
int i = lower_bound(s_, s_+D, l) - s_;
while(i<D && s_[i]<=r)
{
i = fid(fa_, i);
if(s_[i]>r) break;
if(a[s_[i]]%x == 0)
{
add(s_[i], -a[s_[i]]);
a[s_[i]]/=x;
add(s_[i], a[s_[i]]);
if(a[s_[i]]%x != 0)
{
if(i+1<D) fa_[i] = i+1;
}
}
// cout << i << '\n';
++i;
}
}
int ecnt, hd[N], nt[1000000+23], vr[1000000+23];
void ad(int x, int y) { nt[++ecnt]=hd[x], hd[x]=ecnt, vr[ecnt]=y;}
signed main()
{
n = rd(), m = rd();
for(int i=1; i<=n; ++i)
{
a[i]=rd(); add(i, a[i]); ++c[a[i]]; ad(a[i],i); w=max(w, a[i]);
}
for(int i=2; i<=w; ++i)
for(int j=i+i; j<=w; j+=i)
c[i] += c[j];
c[1] = 0;
for(int i=2; i<=w; ++i) d[i] = d[i-1] + c[i-1];
for(int i=2; i<=w; ++i)
{
int *fa_ = fa + d[i];
for(int j=0; j<c[i]; ++j) fa_[j]=j;
}
for(int i=2;i<=w;++i) {
int *s_ = s + d[i];
for(int j=i;j<=w;j+=i)
for(int x=hd[j]; x; x=nt[x])
s_[n_[i]++] = vr[x];
assert(c[i] == n_[i]);
}
// for(int i=1; i<=w; ++i)
// {
// cout << "#" << i << " : ";
// int *s_ = s + d[i];
// for(int j=0; j<c[i]; ++j) cout << s_[j] << ' ';
// cout << '\n';
// }
ll opt,l,r,x,las=0ll;
while(m--)
{
opt=rd(), l=rd(),r=rd();
l^=las, r^=las;
if(opt == 2) {
las = ask(r) - ask(l-1);
cout << las << '\n';
continue;
}
x=rd();
x^=las;
if(x==1) continue;
div(l,r,x);
}
return 0;
}
回复
共 15 条回复,欢迎继续交流。
正在加载回复...