F——Parenthesis G——Xi and Bo H——修路 I——Binary Search Tree analog

Description

Bobo has a balanced parenthesis sequence P=p 1 p 2…p n of length n and q questions.
The i-th question is whether P remains balanced after p ai and p bi  swapped. Note that questions are individual so that they have no affect on others.
Parenthesis sequence S is balanced if and only if:
1. S is empty;
2. or there exists  balanced parenthesis sequence A,B such that S=AB;
3. or there exists  balanced parenthesis sequence S' such that S=(S').

Input

The input contains at most 30 sets. For each set:
The first line contains two integers n,q (2≤n≤10 5,1≤q≤10 5).
The second line contains n characters p 1 p 2…p n.
The i-th of the last q lines contains 2 integers a i,b i (1≤a i,b i≤n,a i≠b i).

Output

For each question, output " Yes" if P remains balanced, or " No" otherwise.

Sample Input

4 2
(())
1 3
2 3
2 1
()
1 2

Sample Output

No
Yes
No

本来第一反应是利用线段树存储前缀和,然后进行查询,后来实在觉得太麻烦,仔细想想,其实只有”()”这种情况需要讨论.如果询问区间内没有某个位置f(=前的左括号数减右括号数)小于2,则yes,否则no,那么就可以对每个前缀区间统计f,然后前缀区间相减,如果结果大于零就no

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
#include <vector>
#include <map>
#include <set>
using namespace std;
const int maxn=1e5+100;
typedef long long LL;

int n,q;
int sum[maxn];
char str[maxn];

int main()
{
    while (scanf("%d%d",&n,&q)==2)
    {
        scanf("%s",str+1);
        memset(sum,0,sizeof sum);
        int num=0,now=0;
        for (int i=1; i<=n; i++)
        {
            if (str[i]=='(')
            {
                now++;
            }
            else 
            {
                now--;
            }
            if (now<2)
            {
                num++;
            }
            sum[i]=num;
        }
        for (int i=1;i<=q;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if (a>b) 
                swap(a,b);//开始在这里wa了好几发
            if (str[a]=='('&&str[b]==')')
            {
                if(sum[a-1]==sum[b-1])
                {
                    cout<<"Yes"<<endl;
                }
                else
                {
                    cout<<"No"<<endl;
                }
            }
            else 
            {
                cout<<"Yes"<<endl;
            }
        }
    }
    return 0;
}
/**********************************************************************
	Problem: 1809
	User: jk1601zr
	Language: C++
	Result: AC
	Time:196 ms
	Memory:2512 kb
**********************************************************************/

Description

Bo has been in Changsha for four years. However he spends most of his time staying his small dormitory. One day he decides to get out of the dormitory and see the beautiful city. So he asks to Xi to know whether he can get to another bus station from a bus station. Xi is not a good man because he doesn't tell Bo directly. He tells to Bo about some buses' routes. Now Bo turns to you and he hopes you to tell him whether he can get to another bus station from a bus station directly according to the Xi's information.

Input

The first line of the input contains a single integer T (0<T<30) which is the number of test cases. For each test case, the first contains two different numbers representing the starting station and the ending station that Bo asks. The second line is the number n(0<n<=50) of buses' routes which Xi tells. For each of the following n lines, the first number m (2<=m<= 100) which stands for the number of bus station in the bus' route. The remaining m numbers represents the m bus station. All of the bus stations are represented by a number, which is between 0 and 100.So you can think that there are only 100 bus stations in Changsha.

Output

For each test case, output the "Yes" if Bo can get to the ending station from the starting station by taking some of buses which Xi tells. Otherwise output "No". One line per each case. Quotes should not be included.

Sample Input

3
0 3
3
3 1 2 3
3 4 5 6
3 1 5 6
0 4
2
3 0 2 3
2 2 4
3 2
1
4 2 1 0 3

Sample Output

No
Yes
Yes

查询是否有联通块,很容易就想到并查集。

#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <algorithm>
using namespace std;
#define ll long long
const int maxn = 105;

int startnum,endnum;
int n;
int m;
int fa[maxn];
int a[maxn];

int find(int x)
{
    if(fa[x]==x)
        return x;
    else
        return find(fa[x]);
}

int merge(int u,int v)
{
    int fu=find(u);
    int fv=find(v);
    if(fu!=fv)
        fa[fv]=fu;
    return fu!=fv;
}

int main()
{
	int T;
	cin>>T;
	while(T--)
    {
        for(int i=0;i<maxn;i++)
        {
            fa[i]=i;
        }
        cin>>startnum>>endnum;
        cin>>n;
        for(int i=0;i<n;i++)
        {
            cin>>m;
            for(int i=0;i<m;i++)
                cin>>a[i];
            for(int i=1;i<m;i++)
                merge(a[i-1],a[i]);
        }
        if(find(startnum)==find(endnum))
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }
	return 0;
}

/**********************************************************************
	Problem: 1004
	User: jk1601zr
	Language: C++
	Result: AC
	Time:8 ms
	Memory:2024 kb
**********************************************************************/

Description

前段时间,某省发生干旱,B山区的居民缺乏生活用水,现在需要从A城市修一条通往B山区的路。假设有A城市通往B山区的路由m条连续的路段组成,现在将这m条路段承包给n个工程队(≤ ≤ 300)。为了修路的便利,每个工程队只能分配到连续的若干条路段(当然也可能只分配到一条路段或未分配到路段)。假设每个工程队修路的效率一样,即每修长度为1的路段所需的时间为1。现在给出路段的数量m,工程队的数量n,以及m条路段的长度(这m条路段的长度是按照从A城市往B山区的方向依次给出,每条路段的长度均小于1000),需要你计算出修完整条路所需的最短的时间(即耗时最长的工程队所用的时间)。

Input

第一行是测试样例的个数T ,接下来是T个测试样例,每个测试样例占2行,第一行是路段的数量m和工程队的数量n,第二行是m条路段的长度。

Output

对于每个测试样例,输出修完整条路所需的最短的时间。

Sample Input

24 3100 200 300 4009 4250 100 150 400 550 200 50 700 300

Sample Output

400900
思路:类似于最小化最大值,用二分求解。

#include <iostream>
#include <algorithm>
#include <math.h>
#include <cstdio>
#include <string>
#include <string.h>
#include <queue>
#include <set>
using namespace std;
const int maxn=305;

int N,M;
int a[maxn];

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>N>>M;
        int sum=0;int maxl=0;
        for(int i=0;i<N;i++)
        {
            cin>>a[i];
            maxl=max(maxl,a[i]);
            sum+=a[i];
        }
        int l=maxl,r=sum,mid,cnt;
        while(r>l)
        {
            mid=(l+r)/2;
            sum=0;cnt=0;
            for(int i=0;i<N;i++)
            {
                sum+=a[i];
                if(sum>mid)
                {
                    sum=a[i];
                    cnt++;
                }
            }
            if(cnt<M)
                r=mid;
            else
                l=mid+1;
        }
        cout<<l<<endl;
    }
    return 0;
}

/**********************************************************************
	Problem: 1023
	User: jk1601zr
	Language: C++
	Result: AC
	Time:16 ms
	Memory:2024 kb
**********************************************************************/


I——详见https://blog.csdn.net/Abandoninged/article/details/80154361



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值