zoukankan      html  css  js  c++  java
  • 洛谷P1505 [国家集训队]旅游(树剖+线段树)

    传送门

    这该死的码农题……

    把每一条边变为它连接的两个点中深度较浅的那一个,然后就是一堆单点修改/路径查询,不讲了

    这里就讲一下怎么搞路径取反,只要打一个标记就好了,然后把区间和取反,最大最小值交换然后再取反

    单点修改的时候忘记pushdown结果调了好久……

      1 //minamoto
      2 #include<bits/stdc++.h>
      3 #define inf 0x3f3f3f3f
      4 using namespace std;
      5 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
      6 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
      7 inline int read(){
      8     #define num ch-'0'
      9     char ch;bool flag=0;int res;
     10     while(!isdigit(ch=getchar()))
     11     (ch=='-')&&(flag=true);
     12     for(res=num;isdigit(ch=getchar());res=res*10+num);
     13     (flag)&&(res=-res);
     14     #undef num
     15     return res;
     16 }
     17 char sr[1<<21],z[20];int K=-1,Z;
     18 inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
     19 inline void print(int x){
     20     if(K>1<<20)Ot();if(x<0)sr[++K]=45,x=-x;
     21     while(z[++Z]=x%10+48,x/=10);
     22     while(sr[++K]=z[Z],--Z);sr[++K]='
    ';
     23 }
     24 const int N=20005;
     25 int head[N],Next[N<<1],ver[N<<1],edge[N<<1],tot=1;
     26 inline void add(int u,int v,int e){
     27     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
     28 }
     29 int dfn[N],top[N],sz[N],son[N],num[N],val[N],dep[N],fa[N],cnt,n,m;
     30 void dfs1(int u){
     31     sz[u]=1,dep[u]=dep[fa[u]]+1;
     32     for(int i=head[u];i;i=Next[i]){
     33         int v=ver[i];
     34         if(v!=fa[u]){
     35             fa[v]=u,num[i>>1]=v,dfs1(v),sz[u]+=sz[v];
     36             if(sz[son[u]]<sz[v]) son[u]=v;
     37         }
     38     }
     39 }
     40 void dfs2(int u,int t){
     41     top[u]=t,dfn[u]=++cnt;
     42     if(son[u]){
     43         dfs2(son[u],t);
     44         for(int i=head[u];i;i=Next[i])
     45         if(ver[i]!=fa[u]&&ver[i]!=son[u])
     46         dfs2(ver[i],ver[i]);
     47     }
     48 }
     49 int mx[N<<2],mn[N<<2],sum[N<<2],rev[N<<2];
     50 #define ls (p<<1)
     51 #define rs (p<<1|1)
     52 inline void upd(int p){
     53     mx[p]=max(mx[ls],mx[rs]),mn[p]=min(mn[ls],mn[rs]),sum[p]=sum[ls]+sum[rs];
     54 }
     55 inline void ppd(int p){
     56     rev[p]^=1,sum[p]=-sum[p],swap(mn[p],mx[p]),mn[p]=-mn[p],mx[p]=-mx[p];
     57 }
     58 inline void pd(int p){
     59     if(rev[p]){
     60         ppd(ls),ppd(rs);
     61         rev[p]=0;
     62     }
     63 }
     64 void build(int p,int l,int r){
     65     if(l==r) return (void)(mx[p]=mn[p]=sum[p]=val[l]);
     66     int mid=(l+r)>>1;
     67     build(ls,l,mid),build(rs,mid+1,r);
     68     upd(p);
     69 }
     70 void update(int p,int l,int r,int x){
     71     if(l==r) return (void)(mn[p]=mx[p]=sum[p]=val[l]);
     72     int mid=(l+r)>>1;pd(p);
     73     x<=mid?update(ls,l,mid,x):update(rs,mid+1,r,x);
     74     upd(p);
     75 }
     76 void Rev(int p,int l,int r,int ql,int qr){
     77     if(ql<=l&&qr>=r) return (void)(ppd(p));
     78     int mid=(l+r)>>1;pd(p);
     79     if(ql<=mid) Rev(ls,l,mid,ql,qr);
     80     if(qr>mid) Rev(rs,mid+1,r,ql,qr);
     81     upd(p);
     82 }
     83 int querysum(int p,int l,int r,int ql,int qr){
     84     if(ql<=l&&qr>=r) return sum[p];
     85     int mid=(l+r)>>1,res=0;pd(p);
     86     if(ql<=mid) res+=querysum(ls,l,mid,ql,qr);
     87     if(qr>mid) res+=querysum(rs,mid+1,r,ql,qr);
     88     return res;
     89 }
     90 int querymax(int p,int l,int r,int ql,int qr){
     91     if(ql<=l&&qr>=r) return mx[p];
     92     int mid=(l+r)>>1,res=-inf;pd(p);
     93     if(ql<=mid) cmax(res,querymax(ls,l,mid,ql,qr));
     94     if(qr>mid) cmax(res,querymax(rs,mid+1,r,ql,qr));
     95     return res;
     96 }
     97 int querymin(int p,int l,int r,int ql,int qr){
     98     if(ql<=l&&qr>=r) return mn[p];
     99     int mid=(l+r)>>1,res=inf;pd(p);
    100     if(ql<=mid) cmin(res,querymin(ls,l,mid,ql,qr));
    101     if(qr>mid) cmin(res,querymin(rs,mid+1,r,ql,qr));
    102     return res;
    103 }
    104 void change(int i,int x){
    105     val[dfn[num[i]]]=x,update(1,1,n,dfn[num[i]]);
    106 }
    107 void RRR(int u,int v){
    108     while(top[u]!=top[v]){
    109         if(dep[top[u]]<dep[top[v]]) swap(u,v);
    110         Rev(1,1,n,dfn[top[u]],dfn[u]);u=fa[top[u]];
    111     }
    112     if(u!=v){
    113         if(dep[u]<dep[v]) swap(u,v);
    114         Rev(1,1,n,dfn[son[v]],dfn[u]);
    115     }
    116 }
    117 int SUM(int u,int v){
    118     int res=0;
    119     while(top[u]!=top[v]){
    120         if(dep[top[u]]<dep[top[v]]) swap(u,v);
    121         res+=querysum(1,1,n,dfn[top[u]],dfn[u]);u=fa[top[u]];
    122     }
    123     if(u!=v){
    124         if(dep[u]<dep[v]) swap(u,v);
    125         res+=querysum(1,1,n,dfn[son[v]],dfn[u]);
    126     }
    127     return res;
    128 }
    129 int MAX(int u,int v){
    130     int res=-inf;
    131     while(top[u]!=top[v]){
    132         if(dep[top[u]]<dep[top[v]]) swap(u,v);
    133         cmax(res,querymax(1,1,n,dfn[top[u]],dfn[u]));u=fa[top[u]];
    134     }
    135     if(u!=v){
    136         if(dep[u]<dep[v]) swap(u,v);
    137         cmax(res,querymax(1,1,n,dfn[son[v]],dfn[u]));
    138     }
    139     return res;
    140 }
    141 int MIN(int u,int v){
    142     int res=inf;
    143     while(top[u]!=top[v]){
    144         if(dep[top[u]]<dep[top[v]]) swap(u,v);
    145         cmin(res,querymin(1,1,n,dfn[top[u]],dfn[u]));u=fa[top[u]];
    146     }
    147     if(u!=v){
    148         if(dep[u]<dep[v]) swap(u,v);
    149         cmin(res,querymin(1,1,n,dfn[son[v]],dfn[u]));
    150     }
    151     return res;
    152 }
    153 char s[15];
    154 int main(){
    155 //    freopen("testdata.in","r",stdin);
    156     n=read();
    157     for(int i=1,u,v,e;i<n;++i)
    158     u=read()+1,v=read()+1,e=read(),add(u,v,e),add(v,u,e);
    159     dfs1(1),dfs2(1,1);
    160     for(int i=1;i<n;++i) val[dfn[num[i]]]=edge[i<<1];
    161     build(1,1,n);
    162     m=read();
    163     while(m--){
    164         scanf("%s",s+1);int u=read()+1,v=read()+1;
    165         switch(s[1]){
    166             case 'C':--u,--v,change(u,v);break;
    167             case 'N':RRR(u,v);break;
    168             case 'S':print(SUM(u,v));break;
    169             default:{
    170                 print(s[2]=='A'?MAX(u,v):MIN(u,v));
    171                 break;
    172             }
    173         }
    174     }
    175     Ot();
    176     return 0;
    177 }
  • 相关阅读:
    自制“低奢内”CSS3注册表单,包含JS验证哦。请别嫌弃,好吗?。
    自制“低奢内”CSS3登入表单,包含JS验证,请别嫌弃哦。
    到网上收集了一个“高大上”的CSS3登入表单和大家分享一下
    利用:before和:after伪类制作CSS3 圆形按钮 含demo
    Font Awesome 4.0.3 提供了369个网页常用的矢量字体图标,新浪、人人 的矢量图标也到其中哟
    CSS3无前缀脚本prefixfree.js与Animatable使用介绍
    JAVA 利用Dom4j实现英语六级词汇查询 含演示地址
    JAVA中 XML与数据库互转 学习笔记三
    JAVA与DOM解析器提高(DOM/SAX/JDOM/DOM4j/XPath) 学习笔记二
    JAVA与DOM解析器基础 学习笔记
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9799433.html
Copyright © 2011-2022 走看看