题解 牛半仙的妹子图

传送门

名字奇奇怪怪的

容易发现每种颜色产生贡献的最小可接受困难程度就是所有这种颜色的点到源点路径上边权最大值的最小值
所以可以对每种颜色预处理出这个最小值,魔改下spfa就行
然后可以前缀和优化这里的查询,但后一部分\(l,r \leqslant 1e5\)的过不去
发现能处理出查询的\(l,r\)的sum值就行了
考场上思路死在这了,但实际上暴力枚举颜色,用差值计算贡献即可

Code:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 500010
#define ll long long 
//#define int long long 

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m, q, x, op, mod;
int c[N], head[N], size, maxval[N], uni[N], usize, ql[N], qr[N], maxlr, uni2[N<<2], usiz2;
struct edge{int to, next, val;}e[N<<1];
inline void add(int s, int t, int w) {edge* k=&e[++size]; k->to=t; k->val=w; k->next=head[s]; head[s]=size;}

namespace force{
	bool vis[N], visit[N];
	void dfs(int u, int lim) {
		vis[c[u]]=1; visit[u]=1;
		for (int i=head[u],v; i; i=e[i].next) {
			v = e[i].to;
			if (e[i].val<=lim && !visit[v]) dfs(v, lim);
		}
	}
	void solve() {
		for (int i=1,l,r,ans; i<=q; ++i) {
			l=ql[i], r=qr[i]; ans=0;
			for (int j=l; j<=r; ++j) {
				memset(vis, 0, sizeof(vis));
				memset(visit, 0, sizeof(visit));
				dfs(x, j);
				for (int k=1; k<=usize; ++k) if (vis[k]) ++ans;
			}
			printf("%d\n", ans);
		}
		exit(0);
	}
}

namespace task1{
	int dis[N], sum[N], sum2[N];
	bool vis[N];
	void spfa(int s) {
		memset(dis, 127, sizeof(dis));
		queue<int> q;
		int t;
		dis[s]=0; q.push(s);
		while (q.size()) {
			t=q.front(); q.pop();
			vis[t]=0;
			for (int i=head[t],v; i; i=e[i].next) {
				v = e[i].to;
				if (dis[v] > max(dis[t], e[i].val)) {
					dis[v] = max(dis[t], e[i].val);
					if (!vis[v]) q.push(v), vis[v]=1;
				}
			}
		}
		//cout<<"dis: "; for (int i=1; i<=n; ++i) cout<<dis[i]<<' '; cout<<endl;
	}
	void solve() {
		memset(maxval, 127, sizeof(maxval));
		spfa(x);
		for (int i=1; i<=n; ++i) maxval[c[i]]=min(maxval[c[i]], dis[i]);
		//cout<<"maxval: "; for (int i=1; i<=usize; ++i) cout<<maxval[i]<<' '; cout<<endl;
		sort(maxval+1, maxval+usize+1);
		
		for (int i=1; i<=maxlr; ++i) sum[i]=upper_bound(maxval+1, maxval+usize+1, i)-maxval-1;
		for (int i=1; i<=maxlr; ++i) sum2[i]=sum2[i-1]+sum[i];
		
		for (int i=1,l,r,ans; i<=q; ++i) {
			l=ql[i]; r=qr[i];
			//cout<<l<<' '<<r<<endl;
			//for (int j=l; j<=r; ++j) ans+=sum[j]; //, cout<<"+="<<lower_bound(maxval+1, maxval+usize+1, j)-maxval<<endl;
			printf("%d\n", sum2[r]-sum2[l-1]);
		}
		exit(0);
	}
}

namespace task2{
	int dis[N], sum[N], sum2[N];
	bool vis[N];
	void spfa(int s) {
		memset(dis, 127, sizeof(dis));
		queue<int> q;
		int t;
		dis[s]=0; q.push(s);
		while (q.size()) {
			t=q.front(); q.pop();
			vis[t]=0;
			for (int i=head[t],v; i; i=e[i].next) {
				v = e[i].to;
				if (dis[v] > max(dis[t], e[i].val)) {
					dis[v] = max(dis[t], e[i].val);
					if (!vis[v]) q.push(v), vis[v]=1;
				}
			}
		}
		//cout<<"dis: "; for (int i=1; i<=n; ++i) cout<<dis[i]<<' '; cout<<endl;
	}
	void solve() {
		memset(maxval, 127, sizeof(maxval));
		//cout<<double(sizeof(maxval)*6)/1024/1024<<endl; exit(0);
		spfa(x);
		for (int i=1; i<=n; ++i) maxval[c[i]]=min(maxval[c[i]], dis[i]);
		//cout<<"maxval: "; for (int i=1; i<=usize; ++i) cout<<maxval[i]<<' '; cout<<endl;
		sort(maxval+1, maxval+usize+1);
		
		for (int i=1,l,r,ans; i<=q; ++i) {
			l=ql[i]; r=qr[i]; ans=0;
			//cout<<l<<' '<<r<<endl;
			for (int j=l; j<=r; ++j) ans+=upper_bound(maxval+1, maxval+usize+1, j)-maxval-1; //, cout<<"+="<<lower_bound(maxval+1, maxval+usize+1, j)-maxval<<endl;
			printf("%d\n", ans);
		}
		exit(0);
	}
}

namespace task{
	int dis[N]; ll lst;
	bool vis[N];
	void spfa(int s) {
		memset(dis, 127, sizeof(dis));
		queue<int> q;
		int t;
		dis[s]=0; q.push(s);
		while (q.size()) {
			t=q.front(); q.pop();
			vis[t]=0;
			for (int i=head[t],v; i; i=e[i].next) {
				v = e[i].to;
				if (dis[v] > max(dis[t], e[i].val)) {
					dis[v] = max(dis[t], e[i].val);
					if (!vis[v]) q.push(v), vis[v]=1;
				}
			}
		}
		//cout<<"dis: "; for (int i=1; i<=n; ++i) cout<<dis[i]<<' '; cout<<endl;
	}
	ll sum(int k) {
		ll ans=0;
		for (int j=1; j<=usize; ++j) 
			if (maxval[j]<=k) ans+=k-maxval[j]+1;
			else break;
		return ans;
	}
	void solve() {
		memset(maxval, 127, sizeof(maxval));
		spfa(x);
		for (int i=1; i<=n; ++i) maxval[c[i]]=min(maxval[c[i]], dis[i]);
		//cout<<"maxval: "; for (int i=1; i<=usize; ++i) cout<<maxval[i]<<' '; cout<<endl;
		sort(maxval+1, maxval+usize+1);
		for (int i=1,l,r; i<=q; ++i) {
			if (op) {
				l=(ql[i]^lst)%mod+1, r=(qr[i]^lst)%mod+1;
				if (l>r) swap(l, r);
			}
			else l=ql[i], r=qr[i];
			lst=sum(r)-sum(l-1);
			printf("%lld\n", lst);
		}
		exit(0);
	}
}

signed main()
{
	n=read(); m=read(); q=read(); x=read(); op=read();
	if (op) mod=read();
	for (int i=1; i<=n; ++i) c[i]=read(), uni[i]=c[i];
	sort(uni+1, uni+n+1);
	usize=unique(uni+1, uni+n+1)-uni-1;
	for (int i=1; i<=n; ++i) c[i]=lower_bound(uni+1, uni+usize+1, c[i])-uni;
	for (int i=1,u,v,w; i<=m; ++i) {
		u=read(); v=read(); w=read();
		add(u, v, w); add(v, u, w);
	}
	for (int i=1; i<=q; ++i) {
		ql[i]=read(); qr[i]=read(); maxlr=max(maxlr, max(ql[i], qr[i]));
		//uni2[++usiz2]=ql[i]; uni2[++usiz2]=qr[i]; uni2[++usiz2]=ql[i]-1;
	}
	//sort(uni2+1, uni2+usiz2+1);
	//usiz2=unique(uni2+1, uni2+usiz2+1)-uni2-1;
	//if (maxlr>N) task2::solve();
	//else task1::solve();
	//force::solve();
	task::solve();
	
	return 0;
}
posted @ 2021-07-29 21:08  Administrator-09  阅读(12)  评论(0编辑  收藏  举报