zoukankan      html  css  js  c++  java
  • CF145E Lucky Queries

    题目

    CF145E Lucky Queries

    给定一个序列,每一个数是 (4) 或者 (7) ,每次两种操作,翻转一个区间的 (4,7) 或者询问这个序列的最长不降子序列长度。

    分析

    经典的线段树维护的题目。

    考虑维护区间内 (4) 的个数 ,(7) 的个数以及最长不下降子序列长度和最长不上升子序列长度。

    于是区间翻转就很好处理了,直接把四个值两两交换即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    template<typename T>
    inline void read(T &x){
    	x=0;bool f=false;char ch=getchar();
    	while(!isdigit(ch)){f|=ch=='-';ch=getchar();}
    	while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template<typename T>
    inline void write(T x){
    	if(x<0) x=-x,putchar('-');
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    const int N=1e6+5,N1=1e4+5,M=1e7+5;
    #define PII pair<int,int>
    #define pb push_back
    #define fi first
    #define se second
    #define mp make_pair
    #define ll long long
    int n,m,a[N],tag[N<<2];
    int valx[N<<2],valy[N<<2],num4[N<<2],num7[N<<2];//valx:最长不下降,valy:最长不上升 
    inline void Pushup(int x){
    	num4[x]=num4[x<<1]+num4[x<<1|1];
    	num7[x]=num7[x<<1]+num7[x<<1|1];
    	valx[x]=max(valx[x<<1]+num7[x<<1|1],num4[x<<1]+valx[x<<1|1]);
    	valy[x]=max(valy[x<<1]+num4[x<<1|1],num7[x<<1]+valy[x<<1|1]);
    	return ;
    }
    void Build(int x,int l,int r){
    	if(l==r) return num4[x]=(a[l]==4),num7[x]=!num4[x],valx[x]=valy[x]=1,void();
    	int mid=l+r>>1;
    	Build(x<<1,l,mid),Build(x<<1|1,mid+1,r);
    	Pushup(x);return ;
    }
    inline void Pushtag(int x){
    	swap(num4[x],num7[x]),swap(valx[x],valy[x]),tag[x]^=1;
    	return ;
    }
    void PushDown(int x){
    	if(tag[x]) Pushtag(x<<1),Pushtag(x<<1|1);
    	tag[x]=0;
    	return ;
    }
    void Modify(int x,int l,int r,int ql,int qr){
    	if(ql<=l&&r<=qr) return Pushtag(x),void();
    	PushDown(x);int mid=l+r>>1;
    	if(ql<=mid) Modify(x<<1,l,mid,ql,qr);
    	if(qr>mid) Modify(x<<1|1,mid+1,r,ql,qr);
    	Pushup(x);
    	return ;
    }
    signed main(){
    	read(n),read(m);
    	for(register int i=1;i<=n;i++) scanf("%1d",&a[i]);
    	Build(1,1,n);
    	while(m--){
    		int l,r;char op[5];
    		scanf("%s",op);
    		if(op[0]=='c'){
    			write(valx[1]);putchar('
    ');
    			continue;
    		}
    		read(l),read(r);
    		Modify(1,1,n,l,r);
    	}
    	return 0;
    }
    
  • 相关阅读:
    韩式英语
    Daily dictation 听课笔记
    words with same pronunciation
    you will need to restart eclipse for the changes to take effect. would you like to restart now?
    glottal stop(britain fountain mountain)
    education 的发音
    第一次用Matlab 的lamada语句
    SVN的switch命令
    String的split
    SVN模型仓库中的资源从一个地方移动到另一个地方的办法(很久才解决)
  • 原文地址:https://www.cnblogs.com/Akmaey/p/15266207.html
Copyright © 2011-2022 走看看