zoukankan      html  css  js  c++  java
  • 【BZOJ4236】JOIOJI STL

    【BZOJ4236】JOIOJI

    Description

    JOIOJI桑是JOI君的叔叔。“JOIOJI”这个名字是由“J、O、I”三个字母各两个构成的。
    最近,JOIOJI桑有了一个孩子。JOIOJI桑想让自己孩子的名字和自己一样由“J、O、I”三个字母构成,并且想让“J、O、I”三个字母的出现次数恰好相同。
    JOIOJI桑家有一份祖传的卷轴,上面写着一首长诗,长度为N,由“J、O、I”三个字母组成。JOIOJIさん想用诗中最长的满足要求的连续子串作为孩子的名字。
    现在JOIOJI桑将这首长诗交给了你,请你求出诗中最长的、包含同样数目的“J、O、I”三个字母的连续子串。

    Input

    第一行一个正整数N,代表这首长诗的长度
    接下来一行一个长度为N的字符串S,表示这首长诗,保证每个字符都是“J、O、I”三个字母中的一个

    Output

    输出一行一个正整数,代表最长的包含等数量“J、O、I”三个字母的最长连续子串的长度。如果不存在这样的子串,输出0

    Sample Input

    10
    JOIIJOJOOI

    Sample Output

    6

    HINT

    选择“IIJOJO”这个子串,长度为6,包含“J、O、I”三个字母各2个,这是最长的满足要求的子串。
    1<=N<=2*10^5

    题解:本题要求三个字符的数量都相同,我们仍然采用前缀相减的方式,设sj,so,si表示J,O,I的前缀出现次数,那么条件就是:

    sj[i]-sj[j]=so[i]-so[j]=si[i]-si[j]

    移项,得

    sj[i]-so[i]=sj[j]-so[j],sj[i]-si[i]=si[i]-si[j]

    这样就转变成让i和j的两个权值都相等的问题,用map存一下就好了

    然而我一开始忘了map怎么用,手写treap水过~

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cstdlib>
    using namespace std;
    const int maxn=200010;
    int rt[maxn<<1],ch[maxn][2],v[maxn],k[maxn],w[maxn];
    int n,tot,s1,s2,s3,ans;
    char str[maxn];
    void rotate(int &x,int d)
    {
    	int y=ch[x][d];
    	ch[x][d]=ch[y][d^1];
    	ch[y][d^1]=x;
    	x=y;
    }
    void insert(int &x,int y,int z)
    {
    	if(!x)
    	{
    		x=++tot;
    		v[x]=y,w[x]=z,k[x]=rand();
    		return ;
    	}
    	int d=y<v[x]?0:1;
    	insert(ch[x][d],y,z);
    	if(k[ch[x][d]]>k[x])	rotate(x,d);
    }
    int find(int x,int y)
    {
    	if(!x)	return 0;
    	if(y==v[x])	return x;
    	if(y<v[x])	return find(ch[x][0],y);
    	return find(ch[x][1],y);
    }
    int main()
    {
    	srand(2333333);
    	scanf("%d",&n);
    	scanf("%s",str);
    	int i;
    	insert(rt[n],0,0);
    	for(i=1;i<=n;i++)
    	{
    		if(str[i-1]=='J')	s1++;
    		if(str[i-1]=='O')	s2++;
    		if(str[i-1]=='I')	s3++;
    		int t=find(rt[s1-s2+n],s2-s3);
    		if(!t)	insert(rt[s1-s2+n],s2-s3,i);
    		else	ans=max(ans,i-w[t]);
    	}
    	printf("%d",ans);
    	return 0;
    }
  • 相关阅读:
    redis学习教程三《发送订阅、事务、连接》
    redis学习教程二《四大数据类型》
    redis学习教程一《Redis的安装和配置》
    java架构《并发编程框架篇 __Disruptor》
    java架构《并发线程高级篇四》
    java架构《并发线程高级篇三》
    java架构《并发线程高级篇二》
    java架构《并发线程高级篇一》
    java架构《并发线程中级篇》
    java架构《并发线程基础二》
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6617263.html
Copyright © 2011-2022 走看看