zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",ans);
    	return 0;
    }
    

    C

    三重容斥,毒瘤

  • 相关阅读:
    eclipse下c/cpp " undefined reference to " or "launch failed binary not found"问题
    blockdev 设置文件预读大小
    宝宝语录
    CentOS修改主机名(hostname)
    subprocess报No such file or directory
    用ldap方式访问AD域的的错误解释
    英特尔的VTd技术是什么?
    This virtual machine requires the VMware keyboard support driver which is not installed
    Linux内核的文件预读详细详解
    UNP总结 Chapter 26~29 线程、IP选项、原始套接字、数据链路访问
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/9420852.html
Copyright © 2011-2022 走看看