Live2D

CF1588F Jumping Through the Array

link

Solution

md,摆了一周,现在是彻底废了/kk

可以看出的是这玩意是若干个个环,不过我们会发现,这个性质没有什么用。

发现不好做,考虑操作分块。我们可以发现对于操作 \(1\) 我们现在就可以在操作 \(2\) 的时候考虑其产生的贡献。发现棘手的地方在于操作 \(3\) 直接改变了图的形状,所以似乎我们只能暴力。但是,我们发现很多点都是一起操作的,我们完全可以缩点。仔细观察可以发现,其实我们把 \(2,3\) 操作涉及到的点设为关键点,一个点染色为环上面它后面最近的关键点,那么同一颜色显然可以一起操作。又因为只有 \(\sqrt n\) 个关键点,所以直接暴力就是 \(\Theta(n\sqrt n)\)

当然了,在知道是操作分块后还不会做的我自然是个nc。

Code

#include <bits/stdc++.h>
using namespace std;
     
#define Int register int
#define int long long
#define MAXN 200005
#define MAXM 1305

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}

bool vis[MAXN];
int n,m,cnt,tot,a[MAXN],b[MAXN],p[MAXN],sum[MAXN],ind[MAXN],pre[MAXN],col[MAXN],add[MAXN],siz[MAXM][MAXM];

void color (int x,int y){while (!col[x]) col[x] = y,x = pre[x];}
void addit (int x,int y){while (!vis[x]) add[x] += y,vis[x] = 1,x = col[p[x]];while (vis[x]) vis[x] = 0,x = col[p[x]];}

struct node{
	int opt,x,y;
}seq[MAXN];

signed main(){
	read (n);
	for (Int x = 1;x <= n;++ x) read (a[x]);
	for (Int x = 1;x <= n;++ x) read (p[x]),pre[p[x]] = x;
	read (m);int Siz = sqrt (m);
	for (Int L = 1;L <= m;L += Siz){
		int R = min (m,L + Siz - 1);
		cnt = tot = 0,memset (ind,0,sizeof (ind)),memset (add,0,sizeof (add)),memset (col,0,sizeof (col));
		for (Int x = 1;x <= n;++ x) sum[x] = sum[x - 1] + a[x];
		for (Int t = L;t <= R;++ t){
			read (seq[t].opt,seq[t].x,seq[t].y);
			if (seq[t].opt == 1){
				if (!ind[seq[t].x - 1]) ind[seq[t].x - 1] = ++ cnt;
				if (!ind[seq[t].y]) ind[seq[t].y] = ++ cnt;  
			}
			else if (seq[t].opt == 2) col[seq[t].x] = seq[t].x;
			else col[seq[t].x] = seq[t].x,col[seq[t].y] = seq[t].y;
		}
		for (Int x = 1;x <= n;++ x) if (col[x] == x) b[++ tot] = x,col[x] = 0,color (x,x);
		for (Int x = 0;x <= n;++ x){
			if (x) add[col[x]] ++;
			if (ind[x]) for (Int i = 1;i <= tot;++ i) siz[ind[x]][i] = add[b[i]];
		}
		memset (add,0,sizeof (add));
		for (Int t = L;t <= R;++ t){
			int opt = seq[t].opt,x = seq[t].x,y = seq[t].y;
			if (opt == 1){
				int ans = sum[y] - sum[x - 1];
				for (Int i = 1;i <= tot;++ i) ans += add[b[i]] * (siz[ind[y]][i] - siz[ind[x - 1]][i]);
				write (ans),putchar ('\n');
			}
			else if (opt == 2) addit (x,y);
			else swap (p[x],p[y]),pre[p[x]] = x,pre[p[y]] = y;
		}
		for (Int x = 1;x <= n;++ x) a[x] += add[col[x]];
	}
	return 0;
}
posted @ 2022-11-19 15:47  Dark_Romance  阅读(27)  评论(0编辑  收藏  举报