求一个式子
其中 表示为不经过边权超过
的边,从
开始能够走到的不同颜色点的数量
可以使用前缀和作差,有
那么这个式子的意义就是,每次不经过边权超过 的边权能够到达的不同颜色数量,减去不经过边权超过
能够到达的不同颜色数量.
显然, 与
是有关系的,这个是可以自己手推的
但是对于此题 ,显然需要离散化,而离散化之后
和
之间的数,其值全为
.
那么此题就可做了.
实现代码时用了一个前缀和数组 ,答案就可以
计算,总复杂度
话说我被卡常是没想到的......
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
namespace IO{
#define rep(i,__l,__r) for(signed i=(__l),i##_end_=(__r);i<=i##_end_;++i)
#define fep(i,__l,__r) for(signed i=(__l),i##_end_=(__r);i>=i##_end_;--i)
#define erep(i,u) for(signed i=tail[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writc(a,b) fwrit(a),putchar(b)
#define mp(a,b) make_pair(a,b)
#define fi first
#define se second
typedef long long ll;
// typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef unsigned uint;
#define Endl putchar('\n')
// #define int long long
// #define int unsigned
// #define int unsigned long long
#define cg (c=getchar())
template<class T>inline void readin(T& x){
char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
if(f)x=-x;
}
template<class T>inline T readin(T x){
x=0;char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
return f?-x:x;
}
#undef cg
template<class T>void fwrit(const T x){
if(x<0)return (void)(putchar('-'),fwrit(-x));
if(x>9)fwrit(x/10);
putchar(x%10^48);
}
template<class T>inline T Max(const T x,const T y){return x<y?y:x;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
template<class T>T gcd(const T a,const T b){return b?gcd(b,a%b):a;}
inline void getInv(int inv[],const int lim,const int MOD){
inv[0]=inv[1]=1;for(int i=2;i<=lim;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
}
inline ll mulMod(const ll a,const ll b,const ll mod){//long long multiplie_mod
return ((a*b-(ll)((long double)a/mod*b+1e-8)*mod)%mod+mod)%mod;
}
}
using namespace IO;
#define int long long
const int maxn=5e5;
const int maxm=5e5;
const int inf=1e9+5;
struct edge{int to,nxt,w;}e[maxm*2+5];
int tail[maxn+5],ecnt;
inline void add_edge(const int u,const int v,const int w){
e[++ecnt]=edge{v,tail[u],w};tail[u]=ecnt;
e[++ecnt]=edge{u,tail[v],w};tail[v]=ecnt;
}
int n,m,q,x,opt,M,las;
int c[maxn+5];
inline void Init(){
n=readin(1ll),m=readin(1ll),q=readin(1ll),x=readin(1ll),opt=readin(1ll);
if(opt==1)M=readin(1ll);
rep(i,1,n)c[i]=readin(1ll);
}
int w_arr[maxm+5];
inline void Get_G(){
int u,v;
rep(i,1,m){
u=readin(1ll),v=readin(1ll),w_arr[i]=readin(1ll);
add_edge(u,v,w_arr[i]);
}
}
/** @brief 将边权离散化*/
inline void Get_hash(){
sort(w_arr+1,w_arr+m+1);
m=unique(w_arr+1,w_arr+m+1)-w_arr-1;
rep(i,1,ecnt)e[i].w=lower_bound(w_arr+1,w_arr+m+1,e[i].w)-w_arr;
}
struct node{int u,maxw;
inline int operator <(const node rhs)const{
return !(maxw<rhs.maxw);
}
};
priority_queue<node>Q;
/** @brief 注意, 这里的 f 下标大小为 maxm*/
int f[maxm+5];
/** @brief g[i] = Σ 0~w[i]-1, val[i]*/
int g[maxm+5];
/** @brief 这种颜色被边权为多少时用过*/
int used_col[605];
/** @brief 这个点被 maxw 为多少时到访过*/
int dis[maxn+5];
inline void Dijkstra(){
rep(i,1,n)dis[i]=inf;
rep(i,0,600)used_col[i]=m+1;
Q.push(node{x,0});
dis[x]=0,used_col[c[x]]=0,++f[0];
while(!Q.empty()){
int u=Q.top().u,w=Q.top().maxw;Q.pop();
if(w>dis[u])continue;
// printf("Now u == %lld, w == %lld\n",u,w);
for(int i=tail[u],v,tow;i;i=e[i].nxt){
v=e[i].to,tow=Max(w,e[i].w);
if(tow>=dis[v])continue;
dis[v]=tow;
// printf("When %lld is going to go to %lld, tow == %lld, used_col[c[%lld]] == %lld\n",u,v,tow,v,used_col[c[v]]);
if(tow<used_col[c[v]]){
--f[used_col[c[v]]];
++f[tow];
// printf("++f[%lld]\n",tow);
used_col[c[v]]=tow;
}
Q.push(node{v,tow});
}
}
rep(i,1,m)f[i]+=f[i-1];
g[0]=0;
rep(i,1,m)g[i]=g[i-1]+1ll*(w_arr[i]-w_arr[i-1])*f[i-1];
}
inline void Get_query(){
int l,r,las=0,pl,pr;
while(q--){
// cin>>l>>r;
l=readin(1ll),r=readin(1ll);
if(opt){
l=(l^las)%M+1,r=(r^las)%M+1;
if(l>r)swap(l,r);
}--l;
pl=lower_bound(w_arr+1,w_arr+m+1,l)-w_arr;
if(pl>m)pl=m;
else if(w_arr[pl]>l)--pl;
pr=lower_bound(w_arr+1,w_arr+m+1,r)-w_arr;
if(pr>m)pr=m;
else if(w_arr[pr]>r)--pr;
las=g[pr]+f[pr]-g[pl]-f[pl]+(r-w_arr[pr])*f[pr]-(l-w_arr[pl])*f[pl];
// cout<<las<<'\n';
writc(las,'\n');
}
}
signed main(){
// freopen("sample.in","r",stdin);
// freopen("shit.out","w",stdout);
Init();
Get_G();
Get_hash();
Dijkstra();
Get_query();
return 0;
} 
京公网安备 11010502036488号