zoukankan      html  css  js  c++  java
  • Codeforces Round #698 (Div. 2) E题 Nezzar and Binary String (线段树、逆向思维)

    传送门

    题意

    你需要花(q)天时间将(n)位长的01字符串s变换成指定的01字符串t。在第(i)天,白天你会检查字符串的第(l_i)(r_i)位(包含(l_i,r_i)),如果这些位置上不是全0或者全1,你就会不开心。晚上,你可以偷偷改变(l_i)(r_i)上部分位置的字符,但改变的位置要严格小于[l_i,r_i]位置数的一半。问是否存在一种修改方式能保证你能将s变化到t且保证不出现不开心的情况。

    数据范围

    [1leq nleq 2 imes 10^5 ]

    [0leq qleq 2 imes 10^5 ]

    题解

    这题顺着搞不好搞,但反过来异常好做。我们从字符串t变到字符串s,每天先改变区间([l_i,r_i])的字符再检查区间是否全0或全1,又因为每次只能修改少于半数的字符,所以修改的方式唯一,即如果区间1的个数少于一半则区间变为全0,如果区间内1的个数多于一般,则区间全变为0,如果区间0和1数目相等即均为一半则不能修改,直接输出NO。最后修改完之后,再判断修改过后的字符串是否为s。这里涉及到区间查询,区间修改,建一棵线段树就能搞定。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    #define LL long long
    #define ls (node<<1)
    #define rs (node<<1|1)
    #define fi first
    #define se second
    #define pr pair<int,int>
    #define mk(a,b) make_pair(a,b)
    
    using namespace std;
    int read(){
    	char x=getchar(); int u=0,fg=0;
    	while(!isdigit(x)){ if(x=='-') fg=1; x=getchar(); }
    	while(isdigit(x)){ u=(u<<3)+(u<<1)+(x^48); x=getchar(); }
    	return fg?-u:u;
    }
    const int maxx=2e5+10;
    int tr[maxx<<3],sum[maxx<<3],lazy[maxx<<3];
    char s[maxx],f[maxx];
    pr ask[maxx];
    void push_up(int node){
    	tr[node]=tr[ls]+tr[rs];
    }
    void push_down(int node,int l,int mid,int r){
    	if(!lazy[node]) return;
    	tr[ls]=(lazy[node]-1)*(mid-l+1);
    	tr[rs]=(lazy[node]-1)*(r-mid);
    	lazy[ls]=lazy[node];
    	lazy[rs]=lazy[node];
    	lazy[node]=0;
    }
    void build(int node,int l,int r){
    	lazy[node]=0;
    	if(l>=r){
    		tr[node]=(f[l]-'0');
    //		printf("%d
    ",f[l]-'0');
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(ls,l,mid);
    	build(rs,mid+1,r);
    	push_up(node);
    }
    void update(int node,int l,int r,int ul,int ur,LL x){
    	if(ul<=l && ur>=r){
    		tr[node]=x*(r-l+1);
    		lazy[node]=x+1;
    		return;
    	}
    	int mid=(l+r)>>1;
    	push_down(node,l,mid,r);
    	if(ur<=mid) update(ls,l,mid,ul,ur,x);
    	else if(ul>mid) update(rs,mid+1,r,ul,ur,x);
    	else{
    		update(ls,l,mid,ul,mid,x);
    		update(rs,mid+1,r,mid+1,ur,x);
    	}
    	push_up(node);
    }
    LL query(int node,int l,int r,int ul,int ur){
    	if(ul<=l && ur>=r)  return tr[node];
    	int mid=(l+r)>>1;
    	push_down(node,l,mid,r);
    	if(ur<=mid) return query(ls,l,mid,ul,ur);
    	else if(ul>mid) return query(rs,mid+1,r,ul,ur);
    	else return query(ls,l,mid,ul,mid)+query(rs,mid+1,r,mid+1,ur);
    }
    bool check(int node,int l,int r){
    	if(l>=r){
    		if(tr[node]==0 && s[l]=='0') return 1;
    		else if(tr[node]==1 && s[l]=='1') return 1;
    		else return 0;
    	}
    	int mid=(l+r)>>1;
    	push_down(node,l,mid,r);
    	return check(ls,l,mid)&check(rs,mid+1,r);
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("input.in", "r", stdin);
    	freopen("output.out", "w", stdout);
    #endif
    	int T=read(),n,q;
    	while(T--){
    		n=read(); q=read();
    		scanf("%s",s+1);
    		scanf("%s",f+1);
    		build(1,1,n);
    		For(i,1,q){
    			int u=read(),v=read();
    			ask[i]=mk(u,v);
    		}
    		bool flag=1;
    		for(int i=q;i;--i){
    			int tmp=query(1,1,n,ask[i].fi,ask[i].se),len=ask[i].se-ask[i].fi+1;
    //			printf("%d
    ",tmp);
    			if(tmp*2<len) update(1,1,n,ask[i].fi,ask[i].se,0);
    			else if((len-tmp)*2<len) update(1,1,n,ask[i].fi,ask[i].se,1);
    			else{
    				flag=0;
    				break;
    			}
    		}
    //		cout<<flag<<endl;
    		if(flag) flag=check(1,1,n);
    		if(flag) printf("YES
    ");
    		else printf("NO
    ");
    	}
    	return 0;
    }
  • 相关阅读:
    随机变量数学期望的一个实例
    Form 对象的集合
    并排两个对象对不齐如何解决
    打开PPT 提示安装,非要取消才能显示PPT
    ATL 工程下添加右击菜单
    uva 10273 Eat or Not to Eat?
    python3根据地址批量获取百度地图经纬度
    <数据挖掘导论>读书笔记4--其他分类技术
    <数据挖掘导论>读书笔记6关联分析的高级概念
    <数据挖掘导论>读书笔记5关联分析的基本概念和算法
  • 原文地址:https://www.cnblogs.com/Knowledge-Pig/p/14350961.html
Copyright © 2011-2022 走看看