zoukankan      html  css  js  c++  java
  • nomura2020_e Binary Programming

    nomura2020_e Binary Programming

    https://atcoder.jp/contests/nomura2020/tasks/nomura2020_e

    NjKAB9.png

    Tutorial

    https://img.atcoder.jp/nomura2020/editorial.pdf

    反向考虑,初始串为(T),每次删除一个字符.

    发现所有的0都在1之前删除,考虑如果要删除一个1,那么删除它旁边的1是等价的,如果它旁边有0,那么删除0和它对于后面部分的奇偶性影响相同,而保留1不会更差.

    如果只剩下1,那么依次删除即可,考虑0的删除顺序

    对于连续的1,若长度为偶数,那么无论开始位置,它对于当前局面的贡献都是一样的,所以可以无视,对于奇数的1,类似的,可以变成只有一个1的情况.

    那么一个局面就可以被描述为(a_0,a_1,cdots,a_k),表示开始有(a_0)个0,之后一个1,然后(a_1)个0,...

    考虑每个1贡献的上界,对于第(i)个1,(sum_{j<i} a_j)的大约一半(根据奇偶性是个定值),是它一定会有的贡献,(sum_{jge i}) 是它可能会有的贡献,考虑这个上界是可以达到的.

    可以如此构造,先删去所有(a_0)中的0,然后在(a_1)中保留一个0,其余删除,...,(a_k)中保留一个(0),其余删除,然后从后向前删去所有剩余的0.

    Code

    #include <cassert>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+50;
    int n,k; char T[maxn];
    vector<int> a[maxn];
    namespace seg {
    	const int maxnode=maxn<<2;
    	int sum[maxnode][2];
    	bool rev[maxnode];
    	inline void rever(int u) {
    		rev[u]^=1;
    		swap(sum[u][0],sum[u][1]);
    	}
    	inline void pushdown(int u) {
    		if(rev[u]) {
    			rever(u<<1);
    			rever(u<<1|1);
    			rev[u]=0;
    		}
    	}
    	inline void pushup(int u) {
    		sum[u][0]=sum[u<<1][0]+sum[u<<1|1][0];
    		sum[u][1]=sum[u<<1][1]+sum[u<<1|1][1]; 
    	}
    	void build(int u,int l,int r) {
    		if(l==r) {
    			sum[u][l&1]=T[l]-'0';
    			return;
    		}
    		int mid=(l+r)>>1;
    		build(u<<1,l,mid);
    		build(u<<1|1,mid+1,r);
    		pushup(u);
    	}
    	void update(int u,int l,int r,int qp) {
    		if(l==r) {
    			sum[u][0]=sum[u][1]=0;
    			return;
    		}
    		pushdown(u);
    		int mid=(l+r)>>1;
    		if(qp<=mid) update(u<<1,l,mid,qp);
    		else update(u<<1|1,mid+1,r,qp);
    		pushup(u);
    	}
    	void update(int u,int l,int r,int ql,int qr) {
    		if(l==ql&&r==qr) {
    			rever(u);
    			return;
    		}
    		pushdown(u);
    		int mid=(l+r)>>1;
    		if(qr<=mid) update(u<<1,l,mid,ql,qr);
    		else if(ql>mid) update(u<<1|1,mid+1,r,ql,qr);
    		else {
    			update(u<<1,l,mid,ql,mid);
    			update(u<<1|1,mid+1,r,mid+1,qr);
    		}
    		pushup(u);
    	}
    }
    int main() {
    	scanf("%s",T+1),n=strlen(T+1);
    	for(int i=1;i<=n;++i) {
    		if(T[i]=='0') a[k].push_back(i);
    		else {
    			if(T[i+1]=='1') {++i; continue;}
    			++k;
    		}
    	}
    	if(a[k].size()) ++k;
    	vector<int> ord;
    	for(int i=0;i<k;++i) {
    		for(int j=bool(i);j<a[i].size();++j) ord.push_back(a[i][j]);
    	}
    	for(int i=k-1;i>0;--i) {
    		ord.push_back(a[i][0]);
    	}
    	for(int i=1;i<=n;++i) if(T[i]=='1') ord.push_back(i);
    	seg::build(1,1,n);
    	ll an=0;
    	for(int i=0;i<ord.size();++i) {
    		int x=ord[i];
    		an+=seg::sum[1][1];
    		seg::update(1,1,n,x);
    		seg::update(1,1,n,x,n);
    	}
    	printf("%lld
    ",an);
    	return 0;
    }
    
  • 相关阅读:
    rake db:migrate学会的一些tips
    不提拔你,就因为你只想把工作做好
    jira4r:使用Ruby操作JIRA
    <当下的力量>读书笔记
    Your template was not saved as valid UTF8. 解决方法
    lxml.etree 教程3:Elements carry attributes as a dict
    Ruby目录及文件操作
    体验最火的敏捷SCRUM!(网络直播课程 免费)
    UMLonline技术沙龙:体验一把SCRUM(20121027 广州 免费)
    视频分享:挨踢项目求生法则(1)——团队建设篇
  • 原文地址:https://www.cnblogs.com/ljzalc1022/p/13232353.html
Copyright © 2011-2022 走看看