膜PoPoQQQ:http://blog.csdn.net/popoqqq/article/details/45365043
省选前学动态树分治
跑起来飞快 45s+
看着提交记录 只能说惨不忍睹 爆int呆滞了一早上 还有因为没删文件 没强制在线 RE的
动态树分治 印象中还有 幻想乡战略游戏和捉迷藏
代码注释一大片 丑我也不管了
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#define V G[p].v
using namespace std;
typedef long long ll;
typedef pair<int,long long> data;
typedef vector<data> abcd;
pair<ll,int> operator + (const pair<ll,int> x,const pair<ll,int> y)
{
return make_pair(x.first+y.first,x.second+y.second);
}
pair<ll,int> operator - (const pair<ll,int> x,const pair<ll,int> y)
{
return make_pair(x.first-y.first,x.second-y.second);
}
inline char nc() {
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x) {
char c=nc(),b=1;
for (; !(c>='0' && c<='9'); c=nc()) if (c=='-') b=-1;
for (x=0; c>='0' && c<='9'; x=x*10+c-'0',c=nc());
}
inline void read(ll &x) {
char c=nc(),b=1;
for (; !(c>='0' && c<='9'); c=nc()) if (c=='-') b=-1;
for (x=0; c>='0' && c<='9'; x=x*10+c-'0',c=nc());
}
inline void read(char &x) {
for (x=nc(); x!='C' && x!='G'; x=nc());
}
namespace ST {
int maxn;
ll st[300005][20];
int Log[300005];
inline void Pre(int n,ll *a) {
maxn=n;
for (int i=2; i<=n; i++) Log[i]=Log[i>>1]+1;
for (int i=1; i<=n; i++)
st[i][0]=a[i];
for (int k=1; k<=19; k++)
for (int i=1; i<=n; i++) {
st[i][k]=st[i][k-1];
if (i+(1<<(k-1))<=maxn)
st[i][k]=min(st[i][k-1],st[i+(1<<(k-1))][k-1]);
}
}
inline ll Query(int l,int r) {
if (l>r) swap(l,r);
int t=Log[r-l+1];
return min(st[l][t],st[r-(1<<t)+1][t]);
}
}
struct edge {
int u,v,next;
ll w;
};
edge G[300005];
int head[150005],inum;
inline void add(int u,int v,ll w,int p) {
G[p].u=u; G[p].v=v; G[p].w=w; G[p].next=head[u]; head[u]=p;
}
int n,tot,A;
int a[150005];
ll depth[150005];
int size[150005],del[150005],fat[150005];
ll ia[300005],clk;
int pos[150005];
abcd sum1[150005],sum2[150005];
inline void dfs(int u,int fa) {
ia[++clk]=depth[u];
pos[u]=clk;
for (int p=head[u]; p; p=G[p].next)
if (V!=fa)
{
depth[V]=depth[u]+G[p].w;
dfs(V,u),ia[++clk]=depth[u];
}
}
inline ll dis(int u,int v) {
return depth[u]+depth[v]-2*ST::Query(pos[u],pos[v]);
}
int sum,rt,minimum;
inline void Root(int u,int fa) {
int maximum=0;
size[u]=1;
for (int p=head[u]; p; p=G[p].next)
if (V!=fa && !del[V]) {
Root(V,u);
size[u]+=size[V];
maximum=max(maximum,size[V]);
}
maximum=max(maximum,sum-size[u]);
if (minimum>maximum) minimum=maximum,rt=u;
}
inline void dfs(int u,int fa,ll d,abcd &sum1,abcd &sum2)
{
size[u]=1;
sum1.push_back(data(a[u],d));
sum2.push_back(data(a[u],d));
for (int p=head[u];p;p=G[p].next)
if (V!=fa && !del[V])
dfs(V,u,d+G[p].w,sum1,sum2),size[u]+=size[V];
}
inline void Divi(int u) {
del[u]=1;
sum1[u].push_back(data(a[u],0));
for (int p=head[u]; p; p=G[p].next)
if (!del[V]) {
abcd itmp;
dfs(V,u,G[p].w,sum1[u],itmp);
sum=size[V]; minimum=1<<30;
Root(V,u);
int cg=rt;
fat[cg]=u;
Divi(cg);
sum2[cg]=itmp;
sum2[cg].push_back(data(-1,0));
sort(sum2[cg].begin(),sum2[cg].end());
for(int j=1;j<sum2[cg].size();j++)
sum2[cg][j].second+=sum2[cg][j-1].second;
}
sum1[u].push_back(data(-1,0));
sort(sum1[u].begin(),sum1[u].end());
for(int j=1;j<sum1[u].size();j++)
sum1[u][j].second+=sum1[u][j-1].second;
}
inline pair<ll,int> Query(abcd &a,int l,int r){
if (a.empty())
return pair<ll,int>(0,0);
// for (int j=0;j<a.size();j++)
// printf("(%d,%lld)",a[j].first,a[j].second);
// printf("\n");
abcd::iterator it1=lower_bound(a.begin(),a.end(),data(l,0));
abcd::iterator it2=lower_bound(a.begin(),a.end(),data(r+1,0));
it1--; it2--;
// printf("(%d,%lld)\n",it1->first,it1->second);
// printf("(%d,%lld)\n",it2->first,it2->second);
// printf("%lld\n",it2->second-it1->second);
return make_pair(it2->second-it1->second,it2-it1);
}
inline ll Query(int x,int l,int r){
ll ret=Query(sum1[x],l,r).first;
for (int i=x;fat[i];i=fat[i]){
pair<ll,int> itmp=Query(sum1[fat[i]],l,r)-Query(sum2[i],l,r);
ret+=itmp.first+itmp.second*dis(x,fat[i]);
}
return ret;
}
int main() {
int _u,_v,Q;
ll _w,_a,_b;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(Q); read(A);
for (int i=1; i<=n; i++)
read(a[i]);
for (int i=1; i<n; i++)
read(_u),read(_v),read(_w),add(_u,_v,_w,++inum),add(_v,_u,_w,++inum);
dfs(1,0);
ST::Pre(clk,ia);
minimum=1<<30; sum=n; Root(1,0);
Divi(rt);
/*for (int i=1;i<=n;i++,putchar('\n'))
for (int j=0;j<sum1[i].size();j++)
printf("(%d,%lld)",sum1[i][j].first,sum1[i][j].second);
for (int i=1;i<=n;i++,putchar('\n'))
for (int j=0;j<sum2[i].size();j++)
printf("(%d,%lld)",sum2[i][j].first,sum2[i][j].second);*/
ll lastans=0;
while (Q--)
{
read(_u); read(_a); read(_b);
(_a+=lastans)%=A; (_b+=lastans)%=A;
if (_a>_b) swap(_a,_b);
lastans=Query(_u,_a,_b);
printf("%lld\n",lastans);
}
return 0;
}