2020-09-07

http://icpc.upc.edu.cn/problem.php?cid=2564&pid=7

题目描述

You are working with a strange text editor for texts consisting only of open and close parentheses. The editor accepts the following three keys as editing commands to modify the text kept in it.

·‘(’ appends an open parenthesis (‘(’) to the end of the text.
·‘)’ appends a close parenthesis (‘)’) to the end of the text.
·‘-’ removes the last character of the text.
A balanced string is one of the following.

·“()”
·“(X)” where X is a balanced string
·“XY” where both X and Y are balanced strings
Initially, the editor keeps an empty text. You are interested in the number of balanced substrings in the text kept in the editor after each of your key command inputs. Note that, for the same balanced substring occurring twice or more, their occurrences should be counted separately. Also note that, when some balanced substrings are inside a balanced substring, both the inner and outer balanced substrings should be counted.

输入

The input consists of a single test case given in a line containing a number of characters, each of which is a command key to the editor, that is, either ‘(’, ‘)’, or ‘-’. The number of characters does not exceed 200 000. They represent a key input sequence to the editor.

It is guaranteed that no ‘-’ command comes when the text is empty.

输出

Print the numbers of balanced substrings in the text kept in the editor after each of the key command inputs are applied, each in one line. Thus, the number of output lines should be the same as the number of characters in the input line.

样例输入

【样例1】
(()())—)
【样例2】
()–()()----)(()()))

样例输出

【样例1】
0
0
1
1
3
4
3
1
1
2
【样例2】
0
1
0
0
0
1
1
3
1
1
0
0
0
0
0
1
1
3
4
4

解析

DP动态规划+堆栈+离散化处理

#include <bits/stdc++.h>

using namespace std;
char a[300500]={0};
stack<int>w;
int dp[300500]={0};
int flag[300500]={0};
int main()
{
    scanf("%s",a+1);
    long long sum=0;
    long long s=1;
    for(int i=1;a[i];i++)
    {
        if(a[i]=='(')
        {
            s++;
            w.push(s);
            dp[s]=flag[s]=0;
        }
        if(a[i]==')')
        {
            s++;
            if(!w.empty())
            {
                int u=w.top();
                w.pop();
                dp[s]=dp[u-1]+1;
                flag[s]=u;
                sum+=dp[s];
            }
            else
            {
                dp[s]=flag[s]=0;
            }
        }
        if(a[i]=='-')
        {
            sum-=dp[s];
            while(!w.empty()&&w.top()>=s)
                w.pop();
            if(flag[s]!=0)
                w.push(flag[s]);
            s--;
        }
        printf("%lld\n",sum);
    }
}

http://icpc.upc.edu.cn/problem.php?cid=2573&pid=2

题目描述

It’s easy for ACMer to calculate A^X mod P. Now given seven integers n, A, K, a, b, m, P, and a function f(x) which defined as following.
f(x) = K, x = 1
f(x) = (a*f(x-1) + b)%m , x > 1

Now, Your task is to calculate
( A^(f(1)) + A^(f(2)) + A^(f(3)) + … + A^(f(n)) ) modular P.

输入

In the first line there is an integer T (1 < T <= 40), which indicates the number of test cases, and then T test cases follow. A test case contains seven integers n, A, K, a, b, m, P in one line.
1 <= n <= 10^6
0 <= A, K, a, b <= 10^9
1 <= m, P <= 10^9

输出

For each case, the output format is “Case #c: ans”.
c is the case number start from 1.
ans is the answer of this problem.

样例输入
2
3 2 1 1 1 100 100
3 15 123 2 3 1000 107
样例输出
Case #1: 14
Case #2: 63

参照于
https://blog.youkuaiyun.com/Little_boy_z/article/details/80042689

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
int n,A,K,a,b,m,p;
ll dp1[100500]={0};
ll dp2[100500]={0};
int db()
{
    dp1[0]=dp2[0]=1;
    dp1[1]=A%p;
    for(int i=2;i<=100000;i++)
    {
        dp1[i]=(dp1[i-1]*dp1[1])%p;
    }
    dp2[1]=dp1[100000];
    for(int i=2;i<=100000;i++)
    {
        dp2[i]=(dp2[i-1]*dp2[1])%p;
    }
}
int main()
{
    int t;
    cin>>t;
    for(int j=1;j<=t;j++)
    {
        cin>>n>>A>>K>>a>>b>>m>>p;
        cout<<"Case #"<<j<<": ";
        ll ans=0;
        ll ans2=K;
        db();
        for(int i=1;i<=n;i++)
        {
            ans+=dp1[ans2%100000]*dp2[ans2/100000];
            ans%=p;
            ans2=(ans2*a+b)%m;
        }
        cout<<ans%p<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值