• bzoj4631踩气球


    bzoj4631踩气球

    题意:

    有一个序列和一个区间集合,每次将序列中的一个数-1,求此时集合里有多少个区间和为0。序列大小≤100000,区间数≤100000,操作数≤100000。

    题解:

    此题解法其实并不难,对序列建线段树,用线段树每个节点维护区间和及覆盖该区间的集合内的区间的链表,同时记录每个集合内区间被分割为多少个区间。操作时就把查询经过的节点的区间和-1,如果为0则将覆盖该节点的区间的分割数-1,当分割数为0就让答案++。问题是复杂度,总是要遍历链表不会很慢吗?后来仔细想了一下,每次向线段树挂区间时最多挂log2n个节点,共影响到mlog2n个节点,因此遍历链表的总节点数为mlog2n,且当一个节点区间和变为0遍历链表后就永远不会再遍历,因此总复杂度大致是O(mlog2n)。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define maxn 100100
     6 using namespace std;
     7 
     8 struct nd{int v,n;}; nd nds[maxn*50]; int v[maxn*4],tot[maxn],g[maxn*4],n,m,a[maxn],q,ans,ndss;
     9 inline int read(){
    10     char ch=getchar(); int f=1,x=0;
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    13     return f*x;
    14 }
    15 void ins(int num,int node){
    16     nds[++ndss]=(nd){num,g[node]}; g[node]=ndss;
    17 }
    18 void update(int x){
    19     for(int i=g[x];i;i=nds[i].n){tot[nds[i].v]--; if(!tot[nds[i].v])ans++;}
    20 }
    21 void build(int x,int l,int r){
    22     if(l==r){v[x]=a[l]; return;}; int mid=l+r>>1;
    23     build(x<<1,l,mid); build(x<<1|1,mid+1,r); v[x]=v[x<<1]+v[x<<1|1];
    24 }
    25 void insert(int x,int l,int r,int ql,int qr,int num){
    26     if(ql<=l&&r<=qr){ins(num,x); tot[num]++; return;} int mid=l+r>>1;
    27     if(ql<=mid)insert(x<<1,l,mid,ql,qr,num); if(mid<qr)insert(x<<1|1,mid+1,r,ql,qr,num);
    28 }
    29 void change(int x,int l,int r,int q){
    30     v[x]--; if(!v[x])update(x); if(l==r)return; int mid=l+r>>1;
    31     if(q<=mid)change(x<<1,l,mid,q);else change(x<<1|1,mid+1,r,q);
    32 }
    33 int main(){
    34     //freopen("in.txt","r",stdin);
    35     n=read(); m=read(); inc(i,1,n)a[i]=read(); build(1,1,n);
    36     inc(i,1,m){int l=read(),r=read(); insert(1,1,n,l,r,i);} q=read();
    37     inc(i,1,q){int x=(read()+ans-1)%n+1; change(1,1,n,x); printf("%d
    ",ans);}
    38     return 0;
    39 }

    20160723

  • 相关阅读:
    websocket实现简单的两端双向实时通信
    Carla自动驾驶仿真模拟器基本概念
    vue出镜率比较高的十大面试题
    solidity开发3类型1
    分苹果
    批清除VC临时文件
    ORM框架SQLAchemy的使用
    Yapi————安装部署
    C#中的语句
    C#中的类型转换
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5699496.html
Copyright © 2020-2023  润新知