zoukankan      html  css  js  c++  java
  • 【 SPOJ

    54  种草
    约翰有 N 个牧场,编号为 1 到 N。它们之间有 N 1 条道路,每条道路连接两个牧场。通过这
    些道路,所有牧场都是连通的。
    刚开始的时候,所有道路都是光秃秃的,没有青草。约翰会在一些道路上批量种草。每次开始种
    草的时候,约翰会选择一个牧场作为起点,一个牧场作为终点,找到从起点到终点的最短路径,在这
    条路径上所有的道路上分别种下一棵新的青草。
    贝西在监督约翰的工作,她迫不及待地想知道每条道路上已经有多少青草了。约翰的工作总是被
    贝西打断,他不胜其烦,所以请你来帮忙回答贝西的问题。约翰的工作和贝西的询问是穿插进行的,
    输入数据将会依次出现 M 个事件,以字符 P 开头的事件表示约翰在一条路径上种植了青草,以字符
    Q 开头的事件表示贝西在查询一条道路上有多少青草。
    输入格式
    • 第一行:两个整数 N M, 2 N 105 , 1 M 105
    • 第二行到第 N 行:第 i + 1 行有两个整数 Ui Vi,表示第 i 条道路连接的两个牧场编号,
    1 Ui,Vi N
    • 第 N + 1 行到第 N + Q 行:每行首先由一个大写字母:
    如果是 P,随后会有两个整数 A B,表示约翰在从 A 通向 B 的每条道路上都新种了一
    棵青草, 1 A,B N
    如果是 Q,随后会有两个整数 A B,表示贝西查询一条道路上的青草数量, A B
    这条道路的两个端点, 1 A,B N,保证输入数据中存在一条 A B 的道路
    输出格式
    • 对每个查询请求,输出该条道路上青草的数量,以换行符分隔
    样例输入
    4 6
    1 4
    2 4
    3 4
    P 2 3
    P 1 3
    Q 3 4
    P 1 4
    Q 2 4
    Q 1 4
    样例输出
    212

    【分析】

      因为是树状数组专题,于是我打了树状数组没有打线段树。

      表示人生第一次树状数组的区间修改和区间查询(我太垃圾..

      其实比线段树可还是短多了,就是维护两个东西的前缀和,一个是delta[i],一个是delta[i]*i,delta[i]表示i~n的共同增量。

      具体看我转的那篇东西:http://www.cnblogs.com/Konjakmoyu/p/5981935.html

      然后就是树剖啦ORZ,好多年没打了居然还能打出来ORZ...

    代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<cmath>
      8 using namespace std;
      9 #define Maxn 100010
     10 
     11 struct node
     12 {
     13     int x,y,next;
     14 }t[Maxn*2];int len;
     15 int first[Maxn];
     16 
     17 void ins(int x,int y)
     18 {
     19     t[++len].x=x;t[len].y=y;
     20     t[len].next=first[x];first[x]=len;
     21 }
     22 
     23 char s[10];
     24 
     25 int sm[Maxn],son[Maxn],fa[Maxn],dep[Maxn];
     26 void dfs(int x,int f)
     27 {
     28     sm[x]=1;son[x]=0;fa[x]=f;dep[x]=dep[f]+1;
     29     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
     30     {
     31         int y=t[i].y;
     32         dfs(y,x);
     33         sm[x]+=sm[y];
     34         if(sm[y]>sm[son[x]]) son[x]=y;
     35     }
     36 }
     37 
     38 int tp[Maxn],dfn[Maxn],cnt;
     39 void dfs2(int x,int tpp)
     40 {
     41     if(x==0) return;
     42     dfn[x]=++cnt;tp[x]=tpp;
     43     dfs2(son[x],tpp);
     44     for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x])
     45     {
     46         int y=t[i].y;
     47         if(y==son[x]) continue;
     48         dfs2(y,y);
     49     }
     50 }
     51 
     52 int c1[Maxn],c2[Maxn];
     53 
     54 void ffind(int x,int y,int c)
     55 {
     56     for(int i=x;i<=cnt;i+=i&(-i))
     57         c1[i]+=c,c2[i]+=c*x;
     58     y++;
     59     for(int i=y;i<=cnt;i+=i&(-i))
     60         c1[i]+=-c,c2[i]+=(-c)*y;
     61 }
     62 
     63 int get_ans(int x,int y)
     64 {
     65     int ans=0;
     66     for(int i=y;i>=1;i-=i&(-i))
     67       ans+=(y+1)*c1[i]-c2[i];
     68     x--;
     69     for(int i=x;i>=1;i-=i&(-i))
     70         ans-=(x+1)*c1[i]-c2[i];
     71     return ans;
     72 }
     73 
     74 void change(int x,int y)
     75 {
     76     int tt;
     77     while(tp[x]!=tp[y])
     78     {
     79         if(dep[tp[x]]>dep[tp[y]])
     80         {
     81             tt=x,x=y,y=tt;
     82         }
     83         ffind(dfn[tp[y]],dfn[y],1);
     84         y=fa[tp[y]];
     85     }
     86     if(x==y) return;
     87     if(dep[x]>dep[y]) tt=x,x=y,y=tt;
     88     ffind(dfn[x]+1,dfn[y],1);
     89 }
     90 
     91 int query(int x,int y)
     92 {
     93     int ans=0;
     94     int tt;
     95     while(tp[x]!=tp[y])
     96     {
     97         if(dep[tp[x]]>dep[tp[y]])
     98         {
     99             tt=x,x=y,y=tt;
    100         }
    101         ans+=get_ans(dfn[tp[y]],dfn[y]);
    102         y=fa[tp[y]];
    103     }
    104     if(x==y) return ans;
    105     if(dep[x]>dep[y]) tt=x,x=y,y=tt;
    106     ans+=get_ans(dfn[x]+1,dfn[y]);
    107     return ans;
    108 }
    109 
    110 int main()
    111 {
    112     int n,m;
    113     scanf("%d%d",&n,&m);
    114     len=0;
    115     memset(first,0,sizeof(first));
    116     for(int i=1;i<n;i++)
    117     {
    118         int x,y;
    119         scanf("%d%d",&x,&y);
    120         ins(x,y);ins(y,x);
    121     }
    122     sm[0]=0;dep[0]=0;
    123     dfs(1,0);
    124     cnt=0;
    125     dfs2(1,1);
    126     
    127     memset(c1,0,sizeof(c1));
    128     memset(c2,0,sizeof(c2));
    129     for(int i=1;i<=m;i++)
    130     {
    131         int x,y;
    132         scanf("%s%d%d",s,&x,&y);
    133         if(s[0]=='P')
    134         {
    135             change(x,y);
    136         }
    137         else
    138         {
    139             printf("%d
    ",query(x,y));
    140         }
    141     }
    142     return 0;
    143 }
    【SPOJ GRASSPLA】

    2016-10-28 09:56:44

  • 相关阅读:
    Spring JDBC配置数据源
    Eclipse创建一个Maven Web项目
    部署基于Maven的war文件到Tomcat
    使用“mvn site-deploy”部署站点(WebDAV例子)
    生成基于Maven的项目文档站点
    将项目安装到Maven本地资源库
    使用Maven运行单元测试
    使用Maven清理项目
    使用Maven构建项目
    Dubbo的使用入门
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6006571.html
Copyright © 2011-2022 走看看