zoukankan      html  css  js  c++  java
  • bzoj 5110 Yazid的新生舞会

    题目大意:

    一个数列,求有多少个区间$[l,r]$满足该区间的众数出现次数大于$lceil frac{r-l}{2} ceil$

    思路:

    对于一个区间满足条件的众数明显是唯一的 所以设该数的前缀和数组为$S$

    则一个区间$(l,r]$满足条件满足$2 imes (S_r-S_l)>(r-l)$ 移项后得到$2 imes S_r-r>2 imes S_l-l$

    则对于$2 imes S_i-i$建立函数发现该函数由斜率为$pm 1$组成

    所有函数的关键点总数为$n$ 对于$y$轴建立权值线段树 发现中间连续的一段的贡献为一次函数

    写一波一次函数即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #include<map>
    10 #include<set>
    11 #define rep(i,s,t) for(register int i=(s),i__end=(t);i<=i__end;++i)
    12 #define dwn(i,s,t) for(register int i=(s),i__end=(t);i>=i__end;++i)
    13 #define ren(x) for(register int i=fst[x];i;i=nxt[i])
    14 #define pb(a,x) vec[a].push_back(x);
    15 #define ll long long
    16 #define inf 2139062143
    17 #define MAXN 1001000
    18 using namespace std;
    19 inline int read()
    20 {
    21     int x=0,f=1;char ch=getchar();
    22     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    23     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    24     return x*f;
    25 }
    26 int n,N,tp,g[MAXN],hsh[MAXN],m,tagk[MAXN<<2],tagb[MAXN<<2];
    27 ll sum[MAXN<<2],ans;
    28 vector <int> vec[MAXN];
    29 inline ll calc(ll k,ll b,int x,int y) {return ((ll)((ll)k*y+k*x+2*b)*((ll)y-x+1))/2;}
    30 void pshd(int k,int l,int r,int mid)
    31 {
    32     sum[k<<1]+=calc(tagk[k],tagb[k],l,mid);
    33     sum[k<<1|1]+=calc(tagk[k],tagb[k],mid+1,r);
    34     tagk[k<<1]+=tagk[k],tagk[k<<1|1]+=tagk[k],tagb[k<<1]+=tagb[k],tagb[k<<1|1]+=tagb[k];
    35     tagk[k]=tagb[k]=0LL;
    36 }
    37 void mdf(int k,int l,int r,int a,int b,ll d,ll t)
    38 {
    39     if(l==a&&r==b) {tagb[k]+=t,tagk[k]+=d,sum[k]+=calc(d,t,l,r);return ;}
    40     int mid=l+r>>1;if(tagb[k]!=0||tagk[k]!=0) pshd(k,l,r,mid);
    41     if(b<=mid) mdf(k<<1,l,mid,a,b,d,t);else if(a>mid) mdf(k<<1|1,mid+1,r,a,b,d,t);
    42     else {mdf(k<<1,l,mid,a,mid,d,t);mdf(k<<1|1,mid+1,r,mid+1,b,d,t);}
    43     sum[k]=sum[k<<1]+sum[k<<1|1];
    44 }
    45 ll query(int k,int l,int r,int a,int b)
    46 {
    47     if(l==a&&r==b) return sum[k];
    48     int mid=l+r>>1;if(tagb[k]!=0||tagk[k]!=0) pshd(k,l,r,mid);
    49     if(b<=mid) return query(k<<1,l,mid,a,b);
    50     else if(a>mid) return query(k<<1|1,mid+1,r,a,b);
    51     else return query(k<<1,l,mid,a,mid)+query(k<<1|1,mid+1,r,mid+1,b);
    52 }
    53 void work(int x)
    54 {
    55     int t,las=0,pos;rep(i,1,vec[x].size()-1)
    56     {
    57         t=vec[x][i],pos=las-(t-vec[x][i-1])+1;
    58         ans+=query(1,0,N,pos+n,las+n);
    59         mdf(1,0,N,pos+n+1,las+n+1,1,-pos-n);
    60         if(las+n+2<=N) mdf(1,0,N,las+n+2,N,0,las-pos+1);
    61         las=pos+1;
    62     }
    63     las=0;rep(i,1,vec[x].size()-1)
    64     {
    65         t=vec[x][i],pos=las-(t-vec[x][i-1])+1;
    66         mdf(1,0,N,pos+n+1,las+n+1,-1,pos+n);
    67         if(las+n+2<=N) mdf(1,0,N,las+n+2,N,0,pos-las-1);
    68         las=pos+1;
    69     }
    70 }
    71 int main()
    72 {
    73     n=read(),N=(n<<1)+5,tp=read();rep(i,1,n) {g[i]=read();if(!hsh[g[i]]) hsh[g[i]]=++m;}
    74     rep(i,1,m) pb(i,0);rep(i,1,n) pb(hsh[g[i]],i);rep(i,1,m) pb(i,n+1);
    75     rep(i,1,m) work(i);printf("%lld
    ",ans);
    76 }
    View Code
  • 相关阅读:
    Falsy Bouncer(算法)
    Check for Palindromes(算法)
    ecshop 修改模板可输出php代码
    ecshop显示所有分类树栏目
    ecshop首页调用评论及图片
    ECSHOP 商品评论条件修改——购买过该商品且只能评价一次(购买多少次能评价多少次)
    PS4破解
    Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法
    Java中类方法与实例方法的区别
    Java中类及方法的加载顺序
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10166735.html
Copyright © 2011-2022 走看看