zoukankan      html  css  js  c++  java
  • [LOJ#2732] 「JOISC 2016 Day 2」雇佣计划

    参考博文

    (不过个人感觉我讲的稍微更清楚一点)

     


     

    题目就是让我们求图中满足数值大于等于B的连通块数量

    然后我们可以尝试转换为求连通块两端所产生的“谷”的数量,显然一个连通块对谷可以贡献2的答案,最终答案就是谷的数量除以2

    (下图为查询$B_i$大小为4时的情况,每一个箭头代表一个谷)

    发现每两个数中间的空格都是有可能产生谷的,所以我们只需要维护有多少个空格满足产生谷的条件即可

     

    记一个空格左边的数字为X,右边的数字为Y,当前询问为B,观察发现,当且仅当满足下列条件时,这个空格可以成为谷

    $$min(X,Y)+1 leq B leq max(X,Y)$$

    我们需要一种可以在$logn$的复杂度内维护满足上述条件点的数量,支持单点修改区间查询的数据结构,发现树状数组可以很好的满足这个要求、

     

    我们把这个询问条件差分一下扔到树状数组里维护即可

    一些注意点:

      开始更新的时候要把0和n+1这两个节点也算进去,以免漏记录两端的“谷”

      观察到$a_i$,$b_i$很大,我们需要进行必要的离散化

    代码:

     1 //hgs AK IOI,IMO,ICHO,IPHO
     2 #include<bits/stdc++.h>
     3 #define writeln(x)  write(x),puts("")
     4 #define writep(x)   write(x),putchar(' ')
     5 using namespace std;
     6 inline int read(){
     7     int ans=0,f=1;char chr=getchar();
     8     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
     9     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
    10     return ans*f;
    11 }void write(int x){
    12     if(x<0) putchar('-'),x=-x;
    13     if(x>9) write(x/10);
    14     putchar(x%10+'0');
    15 }const int M= 6e5+5;
    16 int s[M],n,m,x,y,z,b[M],len,v[M];
    17 struct P{int opt,x,y;}q[M];
    18 #define low(x) (x&-x)
    19 inline int  GetNum(int x){return lower_bound(b+1,b+len+1,x)-b;}
    20 inline void Update(int x,int y){for(++x;x<=n*3;x+=low(x))s[x]+=y;}
    21 inline int  Query(int x){int ans=0;for(++x;x;x-=low(x))ans+=s[x];return ans;}
    22 inline void Init(){int tot=0;//离散化 + 树状数组初始化  
    23     for(int i=1;i<=n;i++)b[++tot]=v[i];
    24     for(int i=1;i<=m;i++)if(q[i].opt==1)b[++tot]=q[i].x;else b[++tot]=q[i].y;
    25     sort(b+1,b+tot+1),len=unique(b+1,b+tot+1)-b-1;
    26     for(int i=1;i<=n;i++)v[i]=GetNum(v[i]);
    27     for(int i=1;i<=m;i++)if(q[i].opt==1)q[i].x=GetNum(q[i].x);else q[i].y=GetNum(q[i].y);
    28     for(int i=1;i<=n+1;i++){
    29         int l=v[i-1],r=v[i];
    30         if(l>r)swap(l,r);
    31         Update(++l,1),Update(++r,-1);
    32     }
    33 }
    34 inline void Add(int x,int y){
    35     int l=v[x-1],r=v[x];
    36     if(l>r)swap(l,r);
    37     Update(++l,y),Update(r+1,-y);
    38     l=v[x],r=v[x+1];
    39     if(l>r)swap(l,r);
    40     Update(++l,y),Update(r+1,-y);
    41 }
    42 inline void Solve(){
    43     for(int i=1;i<=m;i++)
    44         if(q[i].opt==1)printf("%d
    ",Query(q[i].x)/2);
    45         else Add(q[i].x,-1),v[q[i].x]=q[i].y,Add(q[i].x,1);
    46 }
    47 int main(){
    48     n=read(),m=read();
    49     for(int i=1;i<=n;i++)v[i]=read();
    50     for(int x,y,z,i=1;i<=m;i++){
    51         if((x=read())==1)q[i].opt=1,q[i].x=read();
    52         else q[i].opt=2,q[i].x=read(),q[i].y=read();
    53     }Init();Solve();
    54     return 0;
    55 }

     

  • 相关阅读:
    仅此一文让你明白ASP.NET MVC 之View的显示
    仅此一文让你明白ASP.NET MVC原理
    MVC4相关Razor语法以及Form表单
    关于jQuery UI 使用心得及技巧
    jQuery编程的最佳实践
    前端不为人知的一面--前端冷知识集锦
    jQuery插件开发精品教程,让你的jQuery提升一个台阶
    常用数据结构及复杂度
    初探12306售票算法
    ajax省市县三级联动
  • 原文地址:https://www.cnblogs.com/zhenglw/p/11780707.html
Copyright © 2011-2022 走看看