社区讨论

求帮忙看下为什么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 条回复,欢迎继续交流。

正在加载回复...