zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 223 F Parenthesis Checking (线段树,前缀和)

    • 题意:有一长度为\(n\)的括号序列,有\(q\)个询问,两种操作,1是交换\(l\)\(r\)位置的字符,2是询问\(l\)\(r\)的括号序列是否合法。

    • 题解:先将括号序列用\(1\)\(-1\)表示,不难发现,对于一个合法的括号序\([l,r]\),其区间和一定为0,且区间内任一位置的前缀和都不能小于\(0\),即前缀和最小值不小于\(0\),那么题目也就转化成了,求区间和以及区间最小值,这里可以用到线段树的一个小技巧,我们只用维护区间最小值,更新的时候\([l,n]\)\([r,n]\)这样区间更新就可以维护前缀和,查询的时候判断一下两个条件是否满足即可。

    • 代码

      #include <bits/stdc++.h>
      #define ll long long
      #define fi first
      #define se second
      #define pb push_back
      #define me memset
      #define rep(a,b,c) for(int a=b;a<=c;++a)
      #define per(a,b,c) for(int a=b;a>=c;--a)
      const int N = 1e6 + 10;
      const int mod = 1e9 + 7;
      const int INF = 0x3f3f3f3f;
      using namespace std;
      typedef pair<int,int> PII;
      typedef pair<ll,ll> PLL;
      ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
      ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
      
      int n,q;
      char s[N];
      int b[N];
      struct Node{
      	int l,r;
      	int mi;
      	int tag;
      }tr[N<<4];
      
      void push_up(int u){
      	tr[u].mi=min(tr[u<<1].mi,tr[u<<1|1].mi);
      }
      
      void push_down(int u){
      	tr[u<<1].mi+=tr[u].tag;
      	tr[u<<1].tag+=tr[u].tag;
      	tr[u<<1|1].mi+=tr[u].tag;
      	tr[u<<1|1].tag+=tr[u].tag;
      	tr[u].tag=0;
      }
      
      void build(int u,int l,int r){
      	if(l==r){
      		tr[u]={l,r};
      		return;
      	}
      	tr[u]={l,r};
      	int mid=(l+r)>>1;
      	build(u<<1,l,mid);
      	build(u<<1|1,mid+1,r);
      	push_up(u);
      }
      
      void update(int u,int L,int R,int x){
      	if(tr[u].l>=L && tr[u].r<=R){
      		tr[u].tag+=x;
      		tr[u].mi+=x;
      		return;
      	}
      	push_down(u);
      	int mid=(tr[u].l+tr[u].r)>>1;
      	if(L<=mid) update(u<<1,L,R,x);
      	if(R>mid) update(u<<1|1,L,R,x);
      	push_up(u);
      }
      
      int query(int u,int L,int R){
      	if(tr[u].l>=L && tr[u].r<=R){
      		return tr[u].mi;
      	}
      	push_down(u);
      	int mid=(tr[u].l+tr[u].r)>>1;
      	int res=INF;
      	if(L<=mid) res=min(res,query(u<<1,L,R));
      	if(R>mid) res=min(res,query(u<<1|1,L,R));
      	return res;
      }
      
      int main() {
      	scanf("%d %d",&n,&q);
      	getchar();
      	scanf("%s",s+1);
      	for(int i=1;i<=n;++i){
      		b[i]=(s[i]=='(')?1:(-1);
      	}
      	build(1,1,n);
      	for(int i=1;i<=n;++i) update(1,i,n,b[i]);
      	while(q--){
      		int op,l,r;
      		scanf("%d %d %d",&op,&l,&r);
      		if(op==1){
      			update(1,l,n,-b[l]);
      			update(1,r,n,-b[r]);
      			swap(b[l],b[r]);
      			update(1,l,n,b[l]);
      			update(1,r,n,b[r]);
      		}
      		else{
      			int pre;
      			if(l==1) pre=0;
      			else pre=query(1,l-1,l-1);
      			if(query(1,r,r)==pre && query(1,l,r)-pre==0) puts("Yes");
      			else puts("No");
      		}
      	}
          return 0;
      }
      
      
      
  • 相关阅读:
    PAT (Basic Level) Practise 1013 数素数
    PAT (Basic Level) Practise 1014 福尔摩斯的约会
    codeforces 814B.An express train to reveries 解题报告
    KMP算法
    rsync工具
    codeforces 777C.Alyona and Spreadsheet 解题报告
    codeforces 798C.Mike and gcd problem 解题报告
    nginx + tomcat多实例
    MongoDB副本集
    指针的艺术(转载)
  • 原文地址:https://www.cnblogs.com/lr599909928/p/15437835.html
Copyright © 2011-2022 走看看