记录编号 |
393010 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HNOI 2015]开店 |
最终得分 |
100 |
用户昵称 |
Cydiater |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
8.090 s |
提交时间 |
2017-04-09 18:53:47 |
内存使用 |
421.84 MiB |
显示代码纯文本
//BZOJ 4012
//by Cydiater
//2017.4.8
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <bitset>
#include <complex>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;++i)
#define down(i,j,n) for(int i=j;i>=n;--i)
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
#define Auto(i,node) for(int i=LINK[node];i;i=e[i].next)
#define FILE "shop_hnoi2015"
const int MAXN=5e5+5;
const int oo=0x3f3f3f3f;
int N,M,val[MAXN],num[MAXN],top=0,fe[MAXN],mod;
ll sum[MAXN],pre[MAXN],dis[MAXN],tol[MAXN],ans=0;
vector<int>S[MAXN];
namespace CMT{
int root[MAXN],cnt;
struct tree{
int son[2];
ll res,tol;
tree(){son[0]=son[1]=res=tol=0;}
}t[MAXN<<5];
int NewNode(int s0,int s1,ll res,ll tol){
cnt++;
t[cnt].son[0]=s0;t[cnt].son[1]=s1;
t[cnt].res=res;t[cnt].tol=tol;
return cnt;
}
void Build(int leftt,int rightt,int &k,int L,int R){
k=NewNode(t[k].son[0],t[k].son[1],t[k].res,t[k].tol);
t[k].res+=sum[min(rightt,R)]-sum[max(leftt,L)-1];
if(leftt>=L&&rightt<=R){
t[k].tol++;
return;
}
int mid=(leftt+rightt)>>1;
if(L<=mid) Build(leftt,mid,t[k].son[0],L,R);
if(R>=mid+1) Build(mid+1,rightt,t[k].son[1],L,R);
}
ll Query(int leftt,int rightt,int k,int L,int R){
if(!k)return 0;
ll res=0;
if(leftt>=L&&rightt<=R) return res+t[k].res;
res+=(sum[min(rightt,R)]-sum[max(leftt,L)-1])*t[k].tol;
int mid=(leftt+rightt)>>1;
if(L<=mid) res+=Query(leftt,mid,t[k].son[0],L,R);
if(mid+1<=R) res+=Query(mid+1,rightt,t[k].son[1],L,R);
return res;
}
}using namespace CMT;
namespace Graph{
struct edge{
int y,next,v;
}e[MAXN<<1];
int LINK[MAXN],len=0,dep[MAXN],dfn[MAXN],Pos[MAXN],dfsclock=0;
int son[MAXN],siz[MAXN],tp[MAXN],fa[MAXN];
inline void insert(int x,int y,int v){
e[++len].next=LINK[x];LINK[x]=len;
e[len].y=y;e[len].v=v;
}
inline void Insert(int x,int y,int v){
insert(x,y,v);
insert(y,x,v);
}
void DFS1(int node,int father,int deep){
fa[node]=father;dep[node]=deep;
siz[node]=1;son[node]=0;fa[node]=father;
Auto(i,node)if(e[i].y!=father){
dis[e[i].y]=dis[node]+e[i].v;
DFS1(e[i].y,node,deep+1);
siz[node]+=siz[e[i].y];
fe[e[i].y]=e[i].v;
if(siz[e[i].y]>siz[son[node]])
son[node]=e[i].y;
}
}
void DFS2(int node,int Top){
tp[node]=Top;Pos[node]=++dfsclock;
dfn[dfsclock]=node;
if(son[node])DFS2(son[node],Top);
Auto(i,node)if(e[i].y!=son[node]&&e[i].y!=fa[node])
DFS2(e[i].y,e[i].y);
}
void Go(int p,int node){
do{
int L=Pos[tp[node]],R=Pos[node];
Build(1,N,root[p],L,R);
node=fa[tp[node]];
}while(node);
}
}using namespace Graph;
namespace solution{
void Prepare(){
scanf("%d%d%d",&N,&M,&mod);
up(i,1,N){
scanf("%d",&val[i]);
num[++top]=val[i];
}
sort(num+1,num+top+1);
top=unique(num+1,num+top+1)-(num+1);
up(i,1,N){
val[i]=lower_bound(num+1,num+top+1,val[i])-num;
S[val[i]].push_back(i);
}
up(i,2,N){
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
Insert(x,y,v);
}
dis[1]=0;
DFS1(1,0,0);
DFS2(1,1);
sum[0]=pre[0]=tol[0]=0;
up(i,1,N)sum[i]=sum[i-1]+fe[dfn[i]];
up(i,1,top){
int size=S[i].size();
root[i]=root[i-1];
pre[i]=pre[i-1];
tol[i]=tol[i-1]+size;
up(j,0,size-1){
int node=S[i][j];
Go(i,node);
pre[i]+=dis[node];
}
}
}
ll Col(ll LIM,int p){
if(LIM<=0)return 0;
ll res=pre[LIM]+tol[LIM]*dis[p],L,R;
do{
L=Pos[tp[p]];
R=Pos[p];
res-=Query(1,N,root[LIM],L,R)*2;
p=fa[tp[p]];
if(p==1)break;
}while(p);
return res;
}
void Solve(){
int L,R;
while(M--){
ll p,a,b;
scanf("%lld%lld%lld",&p,&a,&b);
L=min((a+ans)%mod,(b+ans)%mod);
R=max((a+ans)%mod,(b+ans)%mod);
if(R<num[1]||L>num[top]){
ans=0;
puts("0");
continue;
}
cmin(R,num[top]);
cmax(L,num[1]);
ll tL=lower_bound(num+1,num+top+1,L)-num;
ll tR=lower_bound(num+1,num+top+1,R)-num;
if(R!=num[tR]||tR==top+1)tR--;
L=tL;R=tR;
ans=Col(R,p);
ans-=Col(L-1,p);
printf("%lld\n",ans);
}
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
using namespace solution;
Prepare();
Solve();
return 0;
}