• 暗之链锁


    一道简简单单的差分。。已经身败名裂了。。

    2434. 暗之链锁
    时间限制:1 s 内存限制:256 MB

    【题目描述】
    传说中的暗之连锁被人们称为Dark。Dark是人类内心的黑暗的产物,古今中外的勇者们都试图打倒它。经过研究,你发现Dark呈现无向图的结构,图中有N个节点和两类边,一类边被称为主要边,而另一类被称为附加边。Dark有N – 1条主要边,并且Dark的任意两个节点之间都存在一条只由主要边构成的路径。另外,Dark还有M条附加边。
    你的任务是把Dark斩为不连通的两部分。一开始Dark的附加边都处于无敌状态,你只能选择一条主要边切断。一旦你切断了一条主要边,Dark就会进入防御模式,主要边会变为无敌的而附加边可以被切断。但是你的能力只能再切断
    Dark的一条附加边。现在你想要知道,一共有多少种方案可以击败Dark。注意,就算你第一步切断主要边之后就已经把Dark斩为两截,你也需要切断一条附加边才算击败了Dark。

    【输入格式】
    第一行包含两个整数N和M。
    之后N – 1行,每行包括两个整数A和B,表示A和B之间有一条主要边。
    之后M行以同样的格式给出附加边。

    【输出格式】
    输出一个整数表示答案。

    【样例输入】
    4 1
    1 2
    2 3
    1 4
    3 4

    【样例输出】
    3

    【数据范围】
    对于20% 的数据,N≤100,M≤100。
    对于100% 的数据,N≤100 000,M≤200 000。数据保证答案不超过2^31– 1。


    这道题主要用了树上差分的思想,运用单点更新来求前缀和,来简单的判断是否被经过。
    我们先用树链剖分来求出附加边的lca(其实用其他的方法也可以,只不过树链剖分打得更熟一些)。
    然后就进行差分:
    若x,y为附加边所连的两个节点,那我们称从x到y的树边被覆盖,我们对边的两个节点权+1,其lca的权-2;
    这样就用前缀和成功的可以求出来了!

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 int n,m,x,y,num;
      7 int adj[100001];
      8 struct edge{
      9     int s,t,next;
     10 }k[200001]; 
     11 int read(){
     12     int sum=0;char ch=getchar();
     13     while(ch<'0'||ch>'9') ch=getchar();
     14     while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
     15     return sum;
     16 }
     17 void init(int s,int t){
     18     k[num].s=s;k[num].t=t;
     19     k[num].next=adj[s];adj[s]=num++;
     20 }
     21 int fa[100001],dp[100001],son[100001],size[100001];
     22 void Dfs1(int x){
     23     son[x]=0;size[x]=1;
     24     for(int i=adj[x];i!=-1;i=k[i].next){
     25         int o=k[i].t;
     26         if(o!=fa[x]){
     27             fa[o]=x;dp[o]=dp[x]+1;
     28             Dfs1(o);
     29             size[x]+=size[o];
     30             if(size[son[x]]<size[o])
     31                 son[x]=o;
     32         }
     33     }
     34 }
     35 int top[100001],id[100001],pos[100001],cnt;
     36 int fut[100001];
     37 void Dfs2(int u,int tp){
     38     top[u]=tp;id[u]=++cnt;
     39     pos[cnt]=u;
     40     if(son[u])    
     41         Dfs2(son[u],tp);
     42     for(int i=adj[u];i!=-1;i=k[i].next){
     43         int o=k[i].t;
     44         if(o!=fa[u]&&o!=son[u])
     45             Dfs2(o,o);
     46     } 
     47     fut[u]=cnt;
     48 }
     49 int sum[200001];
     50 int LCA(int x,int y){
     51     int fx=top[x],fy=top[y];
     52     while(fx^fy){
     53         if(dp[fx]<dp[fy]){
     54             swap(fx,fy);
     55             swap(x,y);
     56         }
     57         x=fa[fx];fx=top[x];
     58     }
     59     return dp[x]<dp[y]?x:y;
     60 }
     61 inline int lowbit(int i){
     62     return i&-i;
     63 }
     64 void update(int x,int z){
     65     while(x<=n){
     66         sum[x]+=z;
     67         x+=lowbit(x);
     68     }
     69 }
     70 void change(int x,int y){
     71     int lca=LCA(x,y);
     72     update(id[x],1);
     73     update(id[y],1);
     74     update(id[lca],-2);
     75 }
     76 int gsum(int x){
     77     int ans=0;
     78     while(x){
     79         ans+=sum[x];
     80         x-=lowbit(x);
     81     }
     82     return ans;
     83 }
     84 int ask(int x){
     85     return gsum(fut[x])-gsum(id[x]-1);
     86 }
     87 int main(){
     88     freopen("yam.in","r",stdin);
     89     freopen("yam.out","w",stdout);
     90     memset(adj,-1,sizeof(adj));
     91     n=read();m=read();
     92     for(int i=1;i<n;++i){
     93         x=read();y=read();
     94         init(x,y);init(y,x);
     95     } 
     96     Dfs1(1);Dfs2(1,1);
     97     for(int i=1;i<=m;++i){
     98         x=read();y=read();
     99         change(x,y);
    100     }
    101     int res=0;
    102     for(int i=2;i<=n;++i){
    103         int q=ask(i);
    104         if(q==1)
    105             res++;
    106         if(q==0)
    107             res+=m;
    108     }
    109     printf("%d
    ",res);
    110     // while(1);
    111     return 0;
    112 }
  • 相关阅读:
    HDU 1317 XYZZY(floyd+bellman_ford判环)
    UVa 10791 最小公倍数的最小和(唯一分解定理)
    UVa 12169 不爽的裁判
    UVa 11582 巨大的斐波那契数!(幂取模)
    POJ 1142 Smith Numbers(分治法+质因数分解)
    HDU 1595 find the longest of the shortest
    UVa 11090 在环中
    UVa 10917 林中漫步
    UVa 11374 机场快线
    POJ 1503 Integer Inquiry
  • 原文地址:https://www.cnblogs.com/Maplers/p/7241511.html
Copyright © 2020-2023  润新知