zoukankan      html  css  js  c++  java
  • SPOJ10707 COT2

    题目分析:

    考虑欧拉序,这里的欧拉序与ETT欧拉序的定义相同而与倍增LCA不同。然后不妨对于询问$u$与$v$让$dfsin[u] leq dfsin[v]$,这样对于u和v不在一条路径上,它们可以改成询问$dfsin[u]$到$dfsin[v]$。否则改成$dfsout[u]$到$dfsin[v]$,并加上LCA上的影响,如果在询问过程中没有加入就加入,否则删除。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn = 40200;
      5 const int maxm = 101000;
      6 const int srt = 325;
      7 
      8 int n,m;
      9 int a[maxn],tb[maxn],arr[maxn],fa[maxn],pm[maxm],ans[maxm];
     10 int dfsin[maxn],dfsout[maxn],Num,pre[maxn];
     11 vector <int> g[maxn];
     12 vector <pair<int,int> > Qy[maxn];
     13 struct query{int l,r,bel,rem;}Q[maxm];
     14 
     15 int found(int x){
     16     int rx = x; while(pre[rx] != rx) rx = pre[rx];
     17     while(pre[x] != rx){int tmp = pre[x]; pre[x] = rx; x = tmp;}
     18     return rx;
     19 }
     20 
     21 void dfs(int now,int ff){
     22     arr[now] = 1;pm[++Num] = now;fa[now] = ff;
     23     dfsin[now] = Num;
     24     for(int i=0;i<Qy[now].size();i++){
     25     if(!arr[Qy[now][i].first])continue;
     26     Q[Qy[now][i].second].bel=found(Qy[now][i].first);
     27     }
     28     for(int i=0;i<g[now].size();i++){
     29     if(g[now][i]==fa[now])continue;
     30     dfs(g[now][i],now);
     31     }
     32     pre[now] = fa[now];
     33     pm[++Num] = now; dfsout[now] = Num;
     34 }
     35 
     36 void read(){
     37     scanf("%d%d",&n,&m);
     38     for(int i=1;i<=n;i++) scanf("%d",&a[i]),tb[i] = a[i];
     39     sort(tb+1,tb+n+1);  int num=unique(tb+1,tb+n+1)-tb-1;
     40     for(int i=1;i<=n;i++) a[i]=lower_bound(tb+1,tb+num+1,a[i])-tb;
     41     memset(tb,0,sizeof(tb));
     42     for(int i=1;i<n;i++){
     43     int u,v; scanf("%d%d",&u,&v);
     44     g[u].push_back(v); g[v].push_back(u);
     45     }
     46     for(int i=1;i<=m;i++) scanf("%d%d",&Q[i].l,&Q[i].r);
     47 }
     48 
     49 int cmp(query alpha,query beta){
     50     if(alpha.l/srt == beta.l/srt) return alpha.r < beta.r;
     51     else return alpha.l/srt < beta.l/srt;
     52 }
     53 
     54 void init(){
     55     for(int i=1;i<=m;i++){
     56     Qy[Q[i].l].push_back(make_pair(Q[i].r,i));
     57     Qy[Q[i].r].push_back(make_pair(Q[i].l,i));
     58     }
     59     for(int i=1;i<=n;i++) pre[i] = i;
     60     dfs(1,0);
     61     for(int i=1;i<=m;i++){
     62     if(dfsin[Q[i].l] > dfsin[Q[i].r]) swap(Q[i].l,Q[i].r);
     63     if(Q[i].bel == Q[i].l || Q[i].bel == Q[i].r){
     64         Q[i].l = dfsin[Q[i].l]; Q[i].r = dfsin[Q[i].r];
     65         Q[i].bel = i; Q[i].rem = 0;
     66     }else{
     67         Q[i].l = dfsout[Q[i].l]; Q[i].r = dfsin[Q[i].r];
     68         Q[i].rem = Q[i].bel; Q[i].bel = i;
     69     }
     70     }
     71     sort(Q+1,Q+m+1,cmp);
     72 }
     73 
     74 void work(){
     75     int L = 1,R = 1,as=1; tb[a[1]]++;
     76     for(int i=1;i<=m;i++){
     77     int nowl = Q[i].l,nowr = Q[i].r;
     78     while(R < nowr){
     79         R++;
     80         if(dfsin[pm[R]]==R||dfsin[pm[R]]<L){
     81         if(!tb[a[pm[R]]])as++;
     82         tb[a[pm[R]]]++;
     83         }else{
     84         if(tb[a[pm[R]]] == 1) as--;
     85         tb[a[pm[R]]]--;
     86         }
     87     }
     88     while(L > nowl){
     89         L--;
     90         if(dfsout[pm[L]]==L||dfsout[pm[L]]>R){
     91         if(!tb[a[pm[L]]])as++;
     92         tb[a[pm[L]]]++;
     93         }else{
     94         if(tb[a[pm[L]]] == 1) as--;
     95         tb[a[pm[L]]]--;
     96         }
     97     }
     98     while(R > nowr){
     99         if(dfsin[pm[R]]==R||dfsin[pm[R]]<L){
    100         if(tb[a[pm[R]]] == 1) as--;
    101         tb[a[pm[R]]]--;
    102         }else{
    103         if(!tb[a[pm[R]]])as++;
    104         tb[a[pm[R]]]++;
    105         }
    106         R--;
    107     }
    108     while(L < nowl){
    109         if(dfsout[pm[L]]==L||dfsout[pm[L]]>R){
    110         if(tb[a[pm[L]]] == 1) as--;
    111         tb[a[pm[L]]]--;
    112         }else{
    113         if(!tb[a[pm[L]]])as++;
    114         tb[a[pm[L]]]++;
    115         }
    116         L++;
    117     }
    118     if(Q[i].rem && !tb[a[Q[i].rem]])ans[Q[i].bel]=as+1;
    119     else ans[Q[i].bel] = as;
    120     }
    121     for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    122 }
    123 
    124 int main(){
    125     read();
    126     init();
    127     work();
    128     return 0;
    129 }
  • 相关阅读:
    Sql Server 2016数据库定时备份操作步骤
    .net 生成原图和多张缩略图
    python小知识
    python小知识
    Q pi (lambda)
    GAE&reward shaping
    yield函数
    关于vs code和markdown
    强化学习第七章
    强化学习第六章
  • 原文地址:https://www.cnblogs.com/Menhera/p/9545896.html
Copyright © 2011-2022 走看看