• BZOJ3531 SDOI2014 旅行


    题意:给定一棵树,树上每个点有权值和类型。支持:修改某个点的类型;修改某个点的权值;询问某条链上某个类型的点的和/最大值。点数/类型数/询问数<=100000.

    分析:

    树链剖分,对每个类型的点建立线段树(动态开点)。

    note: 忘记写t_query返回值调半天…… 

    莫名其妙地1A

    代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 int a[5000005],s[5000005],dep[100005],size[100005],vis[100005],top[100005],wson[100005],fa[100005][20],n,m,t1,t2,t3,t4;
      5 int sid[100005],tid[100005],ind,cnt,ch[5000005][2],root[100005],c[100005],w[100005];
      6 vector <int> g[100005];
      7 
      8 void dfs1(int p){
      9     size[p]=1;
     10     vis[p]=1;
     11     for(int i=0;i<g[p].size();i++)
     12         if(vis[g[p][i]]==0)  {
     13             dep[g[p][i]]=dep[p]+1;
     14             fa[g[p][i]][0]=p;
     15             dfs1(g[p][i]);
     16             size[p]+=size[g[p][i]];
     17             if(size[g[p][i]]>size[wson[p]]) wson[p]=g[p][i];
     18         }
     19 }
     20 
     21 void dfs2(int p){
     22     vis[p]=1;
     23     sid[p]=++ind;
     24     tid[ind]=p;
     25     if(wson[p]) {
     26         top[wson[p]]=top[p];
     27         dfs2(wson[p]);
     28     }
     29     for(int i=0;i<g[p].size();i++)
     30         if(vis[g[p][i]]==0) {
     31             top[g[p][i]]=g[p][i];
     32             dfs2(g[p][i]);
     33         }
     34 }
     35 
     36 void lca_presolve() {
     37     for(int i=1;i<=17;i++) 
     38         for(int j=1;j<=n;j++)
     39             fa[j][i]=fa[fa[j][i-1]][i-1];
     40 }
     41 
     42 int lca(int p,int q) {
     43     if(dep[q]>dep[p]) swap(p,q);
     44     for(int i=17;i>=0;i--) if(dep[fa[p][i]]>=dep[q]) p=fa[p][i];
     45     for(int i=17;i>=0;i--) if(fa[p][i]-fa[q][i]) p=fa[p][i],q=fa[q][i];
     46     if(p-q) p=fa[p][0],q=fa[q][0];
     47     return max(p,q);
     48 }
     49 
     50 void init() {
     51     dep[1]=1;
     52     top[1]=1; 
     53     dfs1(1);
     54     memset(vis,0,sizeof vis);
     55     dfs2(1);
     56     lca_presolve();
     57 }
     58 
     59 void modify(int &p,int l,int r,int pos,int k) {
     60     if(p==0) p=++cnt;
     61     if(l==r) {
     62         a[p]=k;
     63         s[p]=k;
     64     }
     65     else {
     66         if(pos<=(l+r)/2) modify(ch[p][0],l,(l+r)/2,pos,k);
     67         else modify(ch[p][1],(l+r)/2+1,r,pos,k);
     68         a[p]=max(a[ch[p][0]],a[ch[p][1]]);
     69         s[p]=s[ch[p][0]]+s[ch[p][1]];
     70     }
     71 }
     72 
     73 void tmodify(int t,int pos,int k) {
     74     modify(root[t],1,2*n,sid[pos],k);
     75 }
     76 
     77 int queryMax(int p,int l,int r,int ql,int qr) {
     78     if(p==0) return 0;
     79     if(l>qr||r<ql) return 0;
     80     if(l>=ql&&r<=qr) return a[p];
     81     return max(queryMax(ch[p][0],l,(l+r)/2,ql,qr),queryMax(ch[p][1],(l+r)/2+1,r,ql,qr));
     82 }
     83 
     84 int querySum(int p,int l,int r,int ql,int qr) {
     85     if(p==0) return 0;
     86     if(l>qr||r<ql) return 0;
     87     if(l>=ql&&r<=qr) return s[p];
     88     return querySum(ch[p][0],l,(l+r)/2,ql,qr)+querySum(ch[p][1],(l+r)/2+1,r,ql,qr);
     89 }
     90 
     91 int lqueryMax(int t,int anc,int son) {
     92     int ans=0;
     93     while(dep[top[son]]>dep[anc]) {
     94         ans=max(ans,queryMax(root[t],1,2*n,sid[top[son]],sid[son]));
     95         son=fa[top[son]][0];
     96     }
     97     ans=max(ans,queryMax(root[t],1,2*n,sid[anc],sid[son]));
     98     return ans;
     99 }
    100 
    101 int lquerySum(int t,int anc,int son) {
    102     int ans=0;
    103     while(dep[top[son]]>dep[anc]) {
    104         ans+=querySum(root[t],1,2*n,sid[top[son]],sid[son]);
    105         son=fa[top[son]][0];
    106     }
    107     ans+=querySum(root[t],1,2*n,sid[anc],sid[son]);
    108     return ans;
    109 }
    110 
    111 int tqueryMax(int t,int p,int q) {
    112     int l=lca(p,q);
    113     return max(lqueryMax(t,l,p),lqueryMax(t,l,q));
    114 }
    115 
    116 int tquerySum(int t,int p,int q) {
    117     int l=lca(p,q);
    118     return lquerySum(t,l,p)+lquerySum(t,l,q)-w[l]*(c[l]==c[p]);
    119 }
    120 
    121 string str;
    122 
    123 int main(){
    124     ios::sync_with_stdio(false);
    125     cin>>n>>m;
    126     for(int i=1;i<=n;i++) {
    127         cin>>t1>>t2;
    128         //tmodify(t2,sid[i],t1);
    129         c[i]=t2;
    130         w[i]=t1;
    131     }
    132     for(int i=1;i<n;i++)  {
    133         cin>>t1>>t2;
    134         g[t1].push_back(t2);
    135         g[t2].push_back(t1);
    136     }
    137     init();
    138     for(int i=1;i<=n;i++) {
    139         tmodify(c[i],i,w[i]);    
    140     }
    141     for(int i=1;i<=m;i++) {
    142         cin>>str>>t1>>t2;
    143         if(str=="CC") {
    144             tmodify(c[t1],t1,0);
    145             tmodify(t2,t1,w[t1]);
    146             c[t1]=t2;
    147         }
    148         if(str=="CW") {
    149             tmodify(c[t1],t1,0);
    150             tmodify(c[t1],t1,t2);
    151             w[t1]=t2;
    152         }
    153         if(str=="QS") {
    154             cout<<tquerySum(c[t1],t1,t2)<<endl;
    155         }
    156         if(str=="QM") {
    157             cout<<tqueryMax(c[t1],t1,t2)<<endl;
    158         }
    159     }
    160 } 
  • 相关阅读:
    springcloud之配置中心和消息总线(配置中心终结版)
    yaml
    RESTful API
    单元测试Junit5
    IDEA社区版创建web项目
    Mybatis常见面试题
    mybatis逆向工程
    mybatis注解
    延迟加载
    缓存
  • 原文地址:https://www.cnblogs.com/mollnn/p/8490666.html
Copyright © 2020-2023  润新知