• 【JZOJ4209】已经没有什么好害怕的了【差分】


    题目大意:

    题目链接:https://jzoj.net/senior/#main/show/4209
    给出一个括号序列,设ansians_i表示经过ii的合法的串,合法的串指所有括号都可以匹配且没有穿插。


    思路:

    next[i]next[i]表示与(前括号)ii相匹配的后括号位置,last[i]last[i]表示与(后括号)ii相匹配的前括号的位置。这个可以用栈O(n)O(n)求出。
    假设这个序列是这样的
    ())((())())(())())((())())(())
    先只看最外层的括号
    ())(......)(......)())(......)(......)
    将无用的括号分离
    ()  (......)(......)() | (......)(......)
    会发现,每个括号所影响到的组数是递增的。
    而每个后括号影响是递减的。
    于是就用差分维护。
    然后对于括号内的,再递归求解即可。
    每个括号最多访问两次,时间复杂度O(n)O(n)


    代码:

    #include <cstdio>
    #include <stack>
    #include <cstring>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    
    const int MOD=1000000007;
    const int N=1000010;
    int T,len,next[N],last[N];
    char ch[N];
    ll sum[N],ans;
    
    void work1(int l,int r)  //前括号差分
    {
    	if (l>r) return;
    	ll k=0;
    	for (int i=r;i>=l;i--)
    		if (last[i])
    		{
    			work1(last[i]+1,i-1);  //递归
    			k++;
    			sum[last[i]]+=k;
    			i=last[i];
    		}
    		else k=0;
    }
    
    void work2(int l,int r)  //后括号
    {
    	if (l>r) return;
    	ll k=0;
    	for (int i=l;i<=r;i++)
    		if (next[i])
    		{
    			work2(i+1,next[i]-1);
    			k++;
    			sum[next[i]+1]-=k;
    			i=next[i];
    		}
    		else k=0;
    }
    
    int main()
    {
    	scanf("%d",&T);
    	while (T--)
    	{
    		memset(sum,0,sizeof(sum));
    		memset(next,0,sizeof(next));
    		memset(last,0,sizeof(last));
    		memset(sum,0,sizeof(sum));
    		scanf("%s",ch+1);
    		len=strlen(ch+1);
    		stack<int> s;
    		for (int i=1;i<=len;i++)
    			if (ch[i]=='(') s.push(i);
    				else if (s.size())
    				{
    					next[s.top()]=i;
    					last[i]=s.top();  //利用栈求
    					s.pop();
    				}
    		work1(1,len);
    		work2(1,len);
    		ans=0;
    		for (int i=1;i<=len;i++)
    		{
    			sum[i]+=sum[i-1];
    			ans+=sum[i]*(ll)i%MOD;
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    ajax调接口示例
    JQuery的ready函数与JS的onload的区别详解
    DIV拖拽
    Lasso估计学习笔记(二)
    Lasso估计论文学习笔记(一)
    ubuntu下部署mongodb以及设置允许远程连接
    C#获取Honeywell voyager 1400g扫码后的数据
    vs2015“当前不会命中断点 还没有为该文档加载任何符号”的解决方法
    pyqt4 python2.7 中文乱码的解决方法
    使用pip 提示UnicodeDecodeError: 'ascii' codec can't decode解决方法
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998378.html
Copyright © 2020-2023  润新知