这里是 $THUWC$ 选拔时间

模拟赛的时候犯 $SB$ 了,写了所有的部分分,然后直接跑过了 $4$ 个大样例(一个大样例是一个特殊情况)……

我还以为我非常叼,部分分都写对了,于是就不管了……

离考试结束还有 $10$ 分钟的时候才发现……程序跑暴力的条件写的是 $$if(n<=5000)\space force::solve();$$

由于 $4$ 个大样例的 $n$ 都只有几百,我之前测的全是暴力……

然后赶紧改改改,测了三个部分分的程序,都小错不断……

于是最后调不完了,自闭 -_-。当做是一次教训吧。

 

题解

这道题的部分分给得很足,所以这里都说一下。

另外,我在下文直接把“新生舞会的数”简称为“众数”,虽然两者定义不一样,但我想少打点字

 

type=1

只要区间内 $0,1$ 的数量不相等,就一定有一个众数($type=3$ 的部分会提到这叫“绝对众数”)。

所以把 $1$ 看成 $1$,$0$ 看成 $-1$,就变成问有多少对不相等的前缀和。

把所有前缀和桶排后随便乘一乘即可。

 

type=2

区间的众数不会出现超过 $15$ 次,也就是说满足要求的区间长度不会超过 $29$。

暴力枚举所有长度为 $1$ 到 $29$ 的区间即可。

 

type=3

此时只有 $8$ 种众数。

由于一个区间内只有一个众数(绝对众数),所以我们可以枚举众数,然后找这个数是哪些区间的众数。

当设众数为 $x$ 时,把 $x$ 记为 $1$,其它数记为 $-1$,那么就是要找所有和 $\ge 1$ 的区间。

改成线性推:假设第 $1$ 到 $i$ 位的和为 $y$(也就是第 $i$ 位的前缀和),那就要快速查找前面有多少和 $\lt y$ 的前缀。

这就是线段树维护前缀和的裸题了。

  1 #include<bits/stdc++.h>
  2 #define N 500005
  3 #define ll long long
  4 #define rep(i,x,y) for(int i=x;i<=y;++i)
  5 #define lc o<<1
  6 #define rc o<<1|1
  7 using namespace std;
  8 inline int read(){
  9     int x=0; bool f=1; char c=getchar();
 10     for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
 11     for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
 12     if(f) return x;
 13     return 0-x;
 14 }
 15 int n,type,a[N];
 16 namespace force{
 17     ll ans;
 18     int cnt[2001][2001];
 19     void solve(){
 20         rep(i,1,n){
 21             int mx=0;
 22             for(int j=0;i+j<=n;++j){
 23                 mx=max(mx,++cnt[i][a[i+j]]);
 24                 if(mx*2>j+1) ++ans;
 25             }
 26         }
 27         cout<<ans<<endl;
 28     }
 29 };
 30 namespace type2{
 31     ll ans;
 32     struct Tree{int siz; bool clr;}tr[N<<2];
 33     int v;
 34     inline void pushdown(int o){
 35         if(tr[o].clr)
 36             tr[lc].siz=tr[rc].siz=0,
 37             tr[lc].clr=tr[rc].clr=1,
 38             tr[o].clr=0;
 39     }
 40     int ins(int o,int l,int r){
 41         ++tr[o].siz;
 42         if(l==r) return tr[o].siz;
 43         pushdown(o);
 44         int mid=(l+r)>>1;
 45         if(v<=mid) return ins(lc,l,mid);
 46         else return ins(rc,mid+1,r);
 47     }
 48     void solve(){
 49         rep(i,1,n){
 50             tr[1].siz=0, tr[1].clr=1;
 51             int mx=0;
 52             for(int j=0; j<29 && i+j<=n; ++j){
 53                 v=a[i+j];
 54                 mx=max(mx,ins(1,0,n-1));
 55                 if(mx*2>j+1) ++ans;
 56             }
 57         }
 58         cout<<ans<<endl;
 59     }
 60 };
 61 namespace type3{
 62     ll ans;
 63     int L=-500000,R,v;
 64     struct Tree{
 65         int siz[N<<2];
 66         void ins(int o,int l,int r){
 67             ++siz[o];
 68             if(l==r) return;
 69             int mid=(l+r)>>1;
 70             if(v<=mid) ins(lc,l,mid);
 71             else ins(rc,mid+1,r);
 72         }
 73         int query(int o,int l,int r){
 74             if(L<=l && r<=R) return siz[o];
 75             int mid=(l+r)>>1, ret=0;
 76             if(L<=mid) ret+=query(lc,l,mid);
 77             if(R>mid) ret+=query(rc,mid+1,r);
 78             return ret;
 79         }
 80     }tr[8];
 81     
 82     int sum[8];
 83     void solve(){
 84         rep(i,0,7) v=0, tr[i].ins(1,-500000,500000);
 85         rep(i,1,n){
 86             rep(j,0,7) --sum[j];
 87             sum[a[i]]+=2;
 88             rep(j,0,7){
 89                 R=sum[j]-1;
 90                 if(L<=R) ans+=tr[j].query(1,-500000,500000);
 91                 v=sum[j];
 92                 tr[j].ins(1,-500000,500000);
 93             }
 94         }
 95         cout<<ans<<endl;
 96     }
 97 };
 98 int main(){
 99     n=read(),type=read();
100     rep(i,1,n) a[i]=read();
101     if(type==0) force::solve();
102     else if(type==1 || type==3) type3::solve();
103     else type2::solve();
104     return 0;
105 }
三个部分分

相关文章:

  • 2021-11-18
  • 2021-08-14
  • 2022-01-07
  • 2021-08-29
  • 2021-05-22
  • 2021-07-08
  • 2021-11-13
  • 2022-01-30
猜你喜欢
  • 2022-01-20
  • 2022-12-23
  • 2022-12-23
  • 2022-02-12
  • 2021-06-09
  • 2021-12-01
  • 2022-12-23
相关资源
相似解决方案