zoukankan      html  css  js  c++  java
  • 解题:HNOI 2015 开店

    题面

    根据树上距离的计算方法,可以先把答案化成$sum dep_i+n*dep_u-sum 2*dep[LCA(i,u)]$的形式,然后维护$sum 2*dep[LCA(i,u)]$

    把妖怪们按年龄排序,轻重剖分后插入每个点到根的路径,记录经过次数,询问也是往根跳然后每次统计边权*次数。

    可持久化线段树+差分

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 const int N=300005,M=1e7+70,inf=1e9;
      6 int root[N],son[M][2],num[M];
      7 int p[N],noww[N],goal[N],val[N];
      8 int siz[N],far[N],imp[N],top[N],dfn[N];
      9 long long dis[N],sum1[N],sum2[N],sum[M],ans;
     10 int n,m,nm,rt,t1,t2,t3,rot,cnt,tot;
     11 struct a
     12 {
     13     int age,idx;
     14 }mon[N];
     15 bool operator < (a x,a y)
     16 {
     17     return x.age==y.age?x.idx<y.idx:x.age<y.age;
     18 }
     19 void Link(int f,int t,int v)
     20 {
     21     noww[++cnt]=p[f],p[f]=cnt;
     22     goal[cnt]=t,val[cnt]=v;
     23     noww[++cnt]=p[t],p[t]=cnt;
     24     goal[cnt]=f,val[cnt]=v;
     25 }
     26 void DFS(int nde,int fth)
     27 {
     28     int tmp=0;
     29     siz[nde]=1,far[nde]=fth;
     30     for(int i=p[nde],g;i;i=noww[i])
     31         if((g=goal[i])!=fth)
     32         {
     33             dis[g]=dis[nde]+val[i];
     34             DFS(g,nde),siz[nde]+=siz[g];
     35             if(siz[g]>tmp) tmp=siz[g],imp[nde]=g;
     36         }
     37 }
     38 void Mark(int nde,int tpp)
     39 {
     40     top[nde]=tpp,dfn[nde]=++tot;
     41     sum1[tot]=dis[nde]-dis[far[nde]];
     42     if(imp[nde])
     43     {
     44         Mark(imp[nde],tpp);
     45         for(int i=p[nde],g;i;i=noww[i])
     46             if((g=goal[i])!=far[nde]&&g!=imp[nde]) Mark(g,g);
     47     }
     48 }
     49 
     50 int Insert(int pre,int l,int r,int ll,int rr)
     51 {
     52     int nde=++tot;
     53     son[nde][0]=son[pre][0];
     54     son[nde][1]=son[pre][1];
     55     num[nde]=num[pre],sum[nde]=sum[pre];
     56     if(l==ll&&r==rr) num[nde]++;
     57     else
     58     {
     59         int mid=(l+r)>>1;
     60         sum[nde]+=sum1[rr]-sum1[ll-1];
     61         if(mid>=rr) son[nde][0]=Insert(son[pre][0],l,mid,ll,rr);
     62         else if(mid<ll) son[nde][1]=Insert(son[pre][1],mid+1,r,ll,rr);
     63         else son[nde][0]=Insert(son[pre][0],l,mid,ll,mid),
     64              son[nde][1]=Insert(son[pre][1],mid+1,r,mid+1,rr);
     65     }
     66     return nde;
     67 }
     68 long long Query(int nde,int l,int r,int ll,int rr)
     69 {
     70     long long ret=(sum1[rr]-sum1[ll-1])*num[nde];
     71     if(l==ll&&r==rr)
     72         return ret+sum[nde];
     73     else
     74     {
     75         int mid=(l+r)>>1;
     76         if(mid>=rr) return ret+Query(son[nde][0],l,mid,ll,rr);
     77         else if(mid<ll) return ret+Query(son[nde][1],mid+1,r,ll,rr);
     78         else return ret+Query(son[nde][0],l,mid,ll,mid)+Query(son[nde][1],mid+1,r,mid+1,rr);
     79     }
     80 }
     81 
     82 int Change(int nde)
     83 {
     84     while(top[nde]!=rt)
     85         rot=Insert(rot,1,n,dfn[top[nde]],dfn[nde]),nde=far[top[nde]];
     86     return rot=Insert(rot,1,n,1,dfn[nde]);
     87 }
     88 long long Ask(int trt,int nde)
     89 {
     90     long long ret=0;
     91     while(top[nde]!=rt)
     92         ret+=Query(trt,1,n,dfn[top[nde]],dfn[nde]),nde=far[top[nde]];
     93     return ret+Query(trt,1,n,1,dfn[nde]);
     94 }
     95 
     96 int main()
     97 {
     98     scanf("%d%d%d",&n,&m,&nm),rt=1;
     99     for(int i=1;i<=n;i++)
    100         scanf("%d",&t1),mon[i]=(a){t1,i};
    101     sort(mon+1,mon+1+n);
    102     for(int i=1;i<n;i++)
    103         scanf("%d%d%d",&t1,&t2,&t3),Link(t1,t2,t3);
    104     DFS(1,0),Mark(1,1);
    105     for(int i=1;i<=n;i++)
    106         sum1[i]+=sum1[i-1],sum2[i]=sum2[i-1]+dis[mon[i].idx];
    107     for(int i=1;i<=n;i++)    
    108         root[i]=Change(mon[i].idx);
    109     for(int i=1;i<=m;i++)
    110     {
    111         scanf("%d%d%d",&t1,&t2,&t3);
    112         t2=(ans+t2)%nm,t3=(ans+t3)%nm;
    113         if(t2>t3) swap(t2,t3);
    114         int ll=lower_bound(mon+1,mon+1+n,(a){t2,0})-mon;
    115         int rr=upper_bound(mon+1,mon+1+n,(a){t3,inf})-mon-1;
    116     //    printf("%d==%d==%d==%d==%d==",ll,rr,dis[t1]*(rr-ll+1),sum2[rr]-sum2[ll-1],2*(Ask(root[rr],t1)-Ask(root[ll-1],t1)));
    117         printf("%lld
    ",ans=dis[t1]*(rr-ll+1)+sum2[rr]-sum2[ll-1]-2*(Ask(root[rr],t1)-Ask(root[ll-1],t1)));
    118     }
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    bzoj 3171 [Tjoi2013]循环格(MCMF)
    spoj 839 Optimal Marks(二进制位,最小割)
    bzoj 1458 士兵占领(最大流)
    bzoj 3931 [CQOI2015]网络吞吐量(最短路,最大流)
    bzoj 2229 [Zjoi2011]最小割(分治+最小割)
    bzoj 1324 Exca王者之剑(黑白染色,最小割)
    BestCoder Round #75 解题报告
    (转)php 根据url自动生成缩略图并处理高并发问题
    PHP生成图片太慢了。。有些都不出来、
    PHP加Nginx实现动态裁剪图片方案
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10534782.html
Copyright © 2011-2022 走看看