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;
}

原文地址:http://www.cnblogs.com/Dark-Romance/p/16906265.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性