ZROI Day1 比赛解题报告

ZROI Day1 比赛解题报告

版权原因不提供题面相关信息


前天晚上搞得比较晚,然后早上做题很没状态,刚看到T1发现没什么思路就有点慌,赶紧看了看T2,T3,
发现T3暴力很好打,T2想了一想可以用数据结构维护一个贪心(感觉我比较能乱搞的只有数据结构)然后码码码,回来看T1还是没什么感觉,随手打了30pts暴力....然后就写炸了,90-->60,真的太菜了

A

现在看确实像是提高难度,有几个显然的性质考场上全都没想到...

  1. 若用\(bit(x)\)表示x在二进制下1的个数,则\(bit(x\) \(xor\) \(y) \%2=(bit(x)+bit(y))\%2\)

  2. 对于区间\([0,m]\),其中二进制下1的个数为偶数的数的个数x为
    • \((m+1)/2\) ---m为奇数
    • \(m/2-1+[m\)有偶数个\(1]\) ---m为偶数

所以只要把区间离散化后统计答案即可,对于一个区间,其中的对数为二进制下有奇数个1的数的个数乘以二进制下有偶数个1的数的个数

B

这题也需要几个性质,很容易手推得到做出的贡献是单调的,于是有个朴素的做法是对于每一个偶数数组,我们枚举此时在它后面插入每一个奇数对答案的贡献,即产生的逆序对,然后取各个的最小值加起来,当然要先预处理加在第一个数前面的情况,时间复杂度\(O(N\) \(log\) \(N)\)

正解其实与上面类似,然而我们是枚举每一个奇数,用数据结构维护它的最优贡献

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <queue>
#define ll long long 
#define ri register int 
using std::min;
template <class T>inline void read(T &x){
    x=0;int ne=0;char c;
    while(!isdigit(c=getchar()))ne=c=='-';
    x=c-48;
    while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
    x=ne?-x:x;return ;
}
const int maxn=200005;
const int inf=0x7fffffff;
int n;
int a[maxn],pos[maxn];
int L,R,dta;
struct Segment_Tree{
    int mi[maxn<<2],tag[maxn<<2];
    void build(int now,int l,int r){
    mi[now]=inf,tag[now]=0;
        if(l==r){
            mi[now]=l;
            return ;
        }
        int mid=(l+r)>>1;
        build(now<<1,l,mid);
        build(now<<1|1,mid+1,r);
        mi[now]=min(mi[now<<1],mi[now<<1|1]);
        return ;
    }
    inline void pushdown(int now){
        if(tag[now]!=0){
        mi[now<<1]+=tag[now];
        mi[now<<1|1]+=tag[now];
        tag[now<<1]+=tag[now];
        tag[now<<1|1]+=tag[now];
        tag[now]=0;
        }
        return ;
    } 
    void update(int now,int l,int r){
        if(L<=l&&r<=R){
            mi[now]+=dta;
            tag[now]+=dta;
            return ;
        }
        int mid=(l+r)>>1;
        pushdown(now);
        if(L<=mid)update(now<<1,l,mid);
        if(mid<R)update(now<<1|1,mid+1,r);
        mi[now]=min(mi[now<<1],mi[now<<1|1]);
        return ;
    }
    int query(int now,int l,int r){
        if(L<=l&&r<=R){
            return mi[now];
        }
        int mid=(l+r)>>1,ans=inf;
        pushdown(now);
        if(L<=mid)ans=min(ans,query(now<<1,l,mid));
        if(mid<R)ans=min(ans,query(now<<1|1,mid+1,r));
        mi[now]=min(mi[now<<1],mi[now<<1|1]);
        return ans;
    }
}T;
struct BIT{
    int b[maxn];
    inline void add(int x,int y){
        for(ri i=x;i<=y;i+=(i&-i)){
            b[i]++;
        }
        return ;
    }
    inline int get(int x){
        int ans=0;
        for(ri i=x;i>0;i-=(i&-i)){
            ans+=b[i];
        }   
        return ans;
    }   
}B;
int main(){
    ll ans=0;
    read(n);
    n=n>>1;
    for(ri i=1;i<=n;i++){
        read(a[i]);
        pos[a[i]]=i;
    }
    for(ri i=n;i>=1;i--){
        ans+=B.get(a[i]);
        B.add(a[i],n<<1);
    }   
    T.build(1,0,n);
    for(ri i=1;i<=n;i++){
        L=0,R=n;
        ans+=T.query(1,0,n);//printf("%d\n",ans);
        int x=pos[i*2];
        L=0,R=x-1,dta=1;
        T.update(1,0,n);
        L=x,R=n,dta=-1;
        T.update(1,0,n);
    }
    printf("%lld\n",ans);
    return 0;
}

C

三重容斥,毒瘤

猜你喜欢

转载自www.cnblogs.com/Rye-Catcher/p/9420852.html