晚測1
阿新 • • 發佈:2020-11-22
A:牛半仙的妹子圖
spfa求出到每個點最少需要多少的困難接受能力
然後對於每個顏色求一下最少的困難接受能力
然後求出每個顏色對於當前次的l到r 貢獻有多少
統計就可以了
因為覺得是原題 所以直接衝了個Kruscal
最小生成樹
然後每次求出一個困難接受能力的答案是多少
然後字首和維護一下區間的答案
最後直接用字首和差分 以及邊界情況的處理就可以了
但是需要套二分 而且需要離散化
寫加調了一個半小時
show code
#include<bits/stdc++.h> using namespace std; #define rint register int #define ll long long const int maxn = 5e5 + 10; const int maxm = 1e3 + 10; int fa[maxn],mp[maxn],head[maxn]; int u[maxn],v[maxn],w[maxn],c[maxn]; int tot,cnt; ll sum[maxn]; ll Sum[maxn]; bitset<maxm> size[maxn]; struct Node{ int id,w; friend bool operator <(const Node &A,const Node &B) {return A.w < B.w;} }as[maxn]; struct node{ int from,next,to,w; friend bool operator <(const node &A,const node &B) {return A.w < B.w;} }a[maxn<<1]; void add(rint x,rint y,rint w){ a[++cnt] = (node) {x,head[x],y,w}; head[x] = cnt; } int find(rint x) {return x == fa[x] ? x : fa[x] = find(fa[x]);} signed main(){ freopen("graph.in","r",stdin); freopen("graph.out","w",stdout); rint n,m,q,x,op,mod; scanf("%d%d%d%d%d",&n,&m,&q,&x,&op); if(op) scanf("%d",&mod); for(rint i = 1;i <= n;++i) scanf("%d",&c[i]),fa[i] = i,size[i][c[i]] = 1; for(rint i = 1;i <= m;++i) scanf("%d%d%d",&u[i],&v[i],&as[i].w),as[i].id = i; sort(as+1,as+m+1); for(rint i = 1;i <= m;++i) { if(as[i].w != as[i-1].w) tot++; w[as[i].id] = tot; mp[tot] = as[i].w; } for(rint i = 1;i <= m;++i) add(u[i],v[i],w[i]); sort(a+1,a+cnt+1); rint j = 1; for(rint i = 1;i <= tot;++i) { while(j <= cnt && a[j].w <= i) { rint u = a[j].from,v = a[j].to; rint fu = find(u),fv = find(v); if(fu == fv) {j++;continue;} fa[fu] = fv; size[fv] |= size[fu]; j++; } sum[i] = size[find(x)].count(); Sum[i] = Sum[i-1] + sum[i] * (mp[i+1] - mp[i]); } sum[0] = 1; ll last = 0; for(rint i = 1;i <= q;++i) { rint l,r; scanf("%d%d",&l,&r); if(op) l = (l ^ last) % mod + 1,r = (r ^ last) % mod + 1; if(l > r) swap(l,r); rint al = l,ar = r; rint L = 1,R = tot; while(L <= R) { rint mid = L + R >> 1; if(mp[mid] > l) R = mid - 1; else L = mid + 1; } l = R; L = 1,R = tot; while(L <= R) { rint mid = L + R >> 1; if(mp[mid] > r) R = mid - 1; else L = mid + 1; } r = R; if(l == r) { last = (ar - mp[r]) * sum[r]; last -= (al - 1 - mp[l]) * sum[l]; printf("%lld\n",last); continue; } last = 0; last += (ar - mp[r] + 1) * sum[r]; last += (mp[l+1] - al) * sum[l]; last += (Sum[r-1] - Sum[l]); printf("%lld\n",last); } return 0; }
##B:牛半仙的妹子Tree