zoukankan      html  css  js  c++  java
  • 【JZOJ3798】临洮巨人

    题目

    题目链接:https://jzoj.net/senior/#main/show/3798

    思路

    半签到题我居然没有做出来\(qwq\)
    \(cnt[x][1/2/3]\)表示前\(i\)个子母中,字母\(A,B,C\)分别出现的次数。
    那么一段区间\([l,r]\)\(A,B,C\)数量相同,当且仅当\(cnt[r][1]-cnt[l-1][1]=cnt[r][2]-cnt[l-1][2]=cnt[r][3]-cnt[l-1][3]\)
    也就是需要分别满足

    • \(cnt[r][1]-cnt[l-1][1]=cnt[r][2]-cnt[l-1][2]\ \to\ cnt[r][1]-cnt[r][2]=cnt[l-1][1]-cnt[l-1][2]\)
    • \(cnt[r][1]-cnt[l-1][1]=cnt[r][3]-cnt[l-1][3]\ \to\ cnt[r][1]-cnt[r][3]=cnt[l-1][1]-cnt[l-1][3]\)

    \(p[i]=cnt[i][1]-cnt[i][2],q[i]=cnt[i][1]-cnt[i][3]\),那么如果有两个位置\(x,y\),满足\(p[x]=p[y]\)\(q[x]=q[y]\)\(x>y\),那么\([y+1,x]\)就是一个满足条件的区间。
    我们考虑把二维压为一维,也就是令\(T[x]=10^6\times p[x]+q[x]\),那么如果\(T[x]=T[y]\)\(y<x\),那么\([y+1,x]\)就是一个满足条件的区间。
    所以就把每个位置的\(T\)求出来,排序然后指针扫描即可。

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    
    const int N=1000010;
    int n,m,num,a[N];
    ll ans,cnt[N][4],T[N];
    char ch[N];
    
    int main()
    {
    	scanf("%s",ch+1);
    	n=strlen(ch+1);
    	for (int i=1;i<=n;i++)
    	{
    		a[i]=ch[i]-'A'+1;
    		cnt[i][1]=cnt[i-1][1]; cnt[i][2]=cnt[i-1][2]; cnt[i][3]=cnt[i-1][3];
    		if (a[i]<=3) cnt[i][a[i]]++;
    		T[i+1]=(cnt[i][1]-cnt[i][2])*1000000LL+cnt[i][1]-cnt[i][3];
    	}
    	n++;
    	sort(T+1,T+1+n);
    	for (int i=1,j=1;i<=n;i=j=j+1)
    	{
    		while (T[j+1]==T[i] && j<n) j++;
    		ans+=1LL*(j-i+1)*(j-i);
    	}
    	printf("%lld",ans/2LL);
    	return 0;
    }
    
  • 相关阅读:
    下标处理问题
    C++输入输出流
    gcc和gdb
    B2C、C2C电子商务分析
    转载:java 动态代理学习(Proxy,InvocationHandler)
    Java Web开发中路径问题小结
    64位操作系统IIS降为32 位版本运行处理
    SQL Server 2000/2005 数据库分页
    iBatis简单入门教程
    JAVA中的Class类
  • 原文地址:https://www.cnblogs.com/stoorz/p/12111288.html
Copyright © 2011-2022 走看看