zoukankan      html  css  js  c++  java
  • HDOJ 5357 Easy Sequence DP


    a[i] 表示以i字符开头的合法序列有多少个

    b[i] 表示以i字符结尾的合法序列有多少个

    up表示上一层的'('的相应位置

    mt[i] i匹配的相应位置

    c[i] 包括i字符的合法序列个数  c[i]=c[up[i]]+a[i]*b[mt[i]]

    括号序列不一定是合法的....

     

    Easy Sequence

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 557    Accepted Submission(s): 165


    Problem Description
    soda has a string containing only two characters -- '(' and ')'. For every character in the string, soda wants to know the number of valid substrings which contain that character.

    Note: 
    An empty string is valid. If S is valid, (S) is valid. If U,V are valid, UV is valid.
     

    Input
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

    A string s consisting of '(' or ')' (1|s|106).
     

    Output
    For each test case, output an integer m=i=1|s|(iansi mod 1000000007), where ansi is the number of valid substrings which contain i-th character.
     

    Sample Input
    2 ()() ((()))
     

    Sample Output
    20 42
    Hint
    For the second case, ans={1,2,3,3,2,1}, then m=11+22+33+43+52+61=42
     

    Source
     

    /* ***********************************************
    Author        :CKboss
    Created Time  :2015年08月10日 星期一 14时24分51秒
    File Name     :HDOJ5357_2.cpp
    ************************************************ */
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <cmath>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    
    using namespace std;
    
    typedef long long int LL;
    
    const int maxn=1001000;
    const LL mod=1e9+7;
    
    int n;
    LL a[maxn],b[maxn],mt[maxn];
    LL c[maxn];
    int up[maxn];
    int stk[maxn],top;
    char str[maxn];
    
    void init(int n)
    {
    	top=0;
    	memset(mt,0,sizeof(mt[0])*n);
    	memset(a,0,sizeof(a[0])*n);
    	memset(b,0,sizeof(b[0])*n);
    	memset(c,0,sizeof(c[0])*n);
    	memset(up,0,sizeof(up[0])*n);
    }
    
    int main()
    {
    	//freopen("in.txt","r",stdin);
    	//freopen("out.txt","w",stdout);
    
    	int T_T;
    	scanf("%d",&T_T);
    	while(T_T--)
    	{
    		scanf("%s",str+1);
    
    		n=strlen(str+1);
    		init(n+10);
    
    		for(int i=1;i<=n;i++)
    		{
    			if(str[i]=='(')
    			{
    				up[i]=stk[top];
    				stk[++top]=i;
    			}
    			else if(top)
    			{
    				int u=stk[top--];
    				mt[u]=i; mt[i]=u;
    				b[i]=b[mt[i]-1]+1;
    			}
    		}
    
    		while(top) mt[stk[top--]]=0;
    
    		for(int i=n;i>=1;i--)
    		{
    			if(str[i]=='('&&mt[i])
    			{
    				a[i]=a[mt[i]+1]+1;
    			}
    		}
    
    		LL ans=0; c[0]=0;
    		for(int i=1;i<=n;i++)
    		{
    			if(str[i]=='('&&mt[i])
    			{
    				c[mt[i]]=c[i]=c[up[i]]+(LL)a[i]*b[mt[i]];
    			}
    			ans+=c[i]*i%mod;
    		}
    
    		cout<<ans<<endl;
    	}
        
        return 0;
    }
    



  • 相关阅读:
    第2课 C 到 C++ 的升级
    第1课 学习 C++ 的意义
    归并排序
    插入排序与希尔排序
    选择排序
    冒泡排序
    CodeSignal 刷题 —— almostIncreasingSequence
    CodeSignal 刷题 —— matrixElementSum
    Python3 序列解包
    单星号变量(*)和双星号变量(**)的用法
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/6961552.html
Copyright © 2011-2022 走看看