题目
分析
考场的时候,根本没有看懂题目 zzz,出题人有毒
这道题的正解其实是一个差分数组的思想
将左括号的位置指向离他最近的有括号后面
左右各算一遍,相加就能得到一个差分数组
得到前缀和,算出答案即可
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #define mo 1000000007 7 #define N 1000005 8 using namespace std; 9 int a[N],l[N],r[N],le[N],ri[N],len=0; 10 char s[N]; 11 long long ans=0,f[N]; 12 void fillchar() 13 { 14 fill(a,a+N,0); 15 fill(l,l+N,0); 16 fill(r,r+N,0); 17 fill(le,le+N,0); 18 fill(ri,ri+N,0); 19 ans=0; 20 } 21 int main() 22 { 23 int T; 24 scanf("%d",&T); 25 while (T--) 26 { 27 fillchar(); 28 int tot=0; 29 scanf("%s",s+1); 30 len=strlen(s+1); 31 for (int i=1;i<=len;i++) 32 if (s[i]=='(') a[++tot]=i; 33 else 34 if (tot!=0) 35 { 36 le[a[tot]]=i+1; 37 ri[i+1]=a[tot--]; 38 } 39 for (int i=len+1;i>=1;i--) 40 { 41 r[i]++; 42 r[ri[i]]+=r[i]; 43 } 44 for (int i=1;i<=len;i++) 45 { 46 l[i]--; 47 l[le[i]]+=l[i]; 48 } 49 for (int i=1;i<=len;i++) 50 f[i]=r[i]+l[i]; 51 for (int i=1;i<=len;i++) 52 f[i]+=f[i-1]; 53 for (int i=1;i<=len;i++) 54 ans=ans+i*f[i]%mo; 55 printf("%lld ",ans); 56 } 57 }