数据结构
【CF380C】 Sereja and Brackets
题目描述
- 本题中「合法括号串」的定义如下:
- 空串是「合法括号串」。
- 若 \(s\) 是「合法括号串」,则 \((s)\) 是「合法括号串」。
- 若 \(s,t\) 是「合法括号串」,则 \(st\) 是「合法括号串」。
- 有一个括号串 \(s\)。\(m\) 次操作。操作有一种:
l r
:求字符串 \(t=s_ls_{l+1}\cdots s_r\) 的所有 子序列 中,长度最长的「合法括号串」,输出长度即可。
- \(1\le |s|\le 10^6\),\(1\le m\le 10^5\)。
解题思路
首先,将 \((,)\) 转化成 \(+1,-1\) ,就是找一个子序列,使得所有的前缀和 \(\ge 0\) ,最后一个前缀和为 \(0\) 。
我们考虑使用线段树,维护没能匹配的 \((\) 数量与没能匹配的 \()\) 数量。
每次两个区间合并时,就是将两区间没匹配的 \(()\) 个配对了进行计算即可。
由于我们默认没匹配的 \((\) 尽量靠前,没匹配的 \()\) 尽量靠后,不会出现匹配不了的问题。
时间复杂度 \(O(nlogn)\) 。
Code
#include<bits/stdc++.h>
using namespace std;
struct datay
{
int v1,v2;
}f[4000005];
string a;
int n,m;
void build(int x,int l,int r)
{
if(l==r)
{
if(a[l]=='(')f[x].v1=1,f[x].v2=0;
else f[x].v1=0,f[x].v2=1;
return;
}
int lc=(x<<1),rc=(x<<1)|1,mid=(l+r)>>1;
build(lc,l,mid),build(rc,mid+1,r);
f[x].v1=f[lc].v1+f[rc].v1-min(f[lc].v1,f[rc].v2);
f[x].v2=f[lc].v2+f[rc].v2-min(f[lc].v1,f[rc].v2);
return;
}
datay query(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)return f[x];
int mid=(l+r)>>1,lc=(x<<1),rc=(x<<1)|1;
if(qr<=mid)return query(lc,l,mid,ql,qr);
if(ql>mid)return query(rc,mid+1,r,ql,qr);
datay z,q=query(lc,l,mid,ql,qr),w=query(rc,mid+1,r,ql,qr);
z.v1=q.v1+w.v1-min(q.v1,w.v2);
z.v2=q.v2+w.v2-min(q.v1,w.v2);
return z;
}
int main()
{
int x,y;datay z;
cin>>a,n=a.size();
a=' '+a,build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y),z=query(1,1,n,x,y);
printf("%d\n",y-x+1-z.v1-z.v2);
}
return 0;
}
【梦熊】 对称之美
题目描述
给出 \(n,k\) \((1 \le n,k \le 10^{14})\) ,求 \(\sum_{i=0}^{k-1} C_{2i}^i n^i (mod\) \(k)\) 。
解题思路
首先,枚举可得,\(k=2\) 时答案为 \(1\) 。
\[C_{2n}^n=\frac{(2n)!}{n! \times n!} =2^n \times \frac{1 \times 3 \times ... \times (2n-1)}{n!} = (-2)^n \times \frac{\prod_{i=0}^{n-1}(k-1-2i)}{n!}=(-4)^n \times \frac{\prod_{i=0}^{n-1}(\frac{k-1}{2}-i)}{n!} \]带回原式并化简,即为:
\[\sum_{i=0}^{k-1} (-4n)^i \times C_{\frac{k-1}{2}}^{i}=(1-4n)^{\frac{k-1}{2}} \]结合二项式定理,由于 \(k\) 较大,需用龟速乘,结合快速幂 \(O(log^2n)\) 解决。
Code
#include<bits/stdc++.h>
using namespace std;
unsigned long long mod;
unsigned long long mul(unsigned long long x,unsigned long long y)
{
unsigned long long h=0;
while(y>0)
{
if(y&1)h=(h+x)%mod;
x=(x+x)%mod,y/=2;
}
return h;
}
unsigned long long poww(unsigned long long x,unsigned long long y)
{
x=(x+mod)%mod;
unsigned long long h=1;
while(y>0)
{
if(y&1)h=mul(h,x);
x=mul(x,x),y/=2;
}
return h;
}
void poi()
{
unsigned long long x,y;
cin>>x>>y;
if(x==1)
{
printf("1\n");
return;
}
mod=x;
cout<<(poww((4*mod+1-4*y)%mod,(mod-1)/2)+mod)%mod<<'\n';
return;
}
int main()
{
unsigned long long qwe;
cin>>qwe;
for(int i=1;i<=qwe;i++)poi();
return 0;
}
标签:总结,lc,2024.7,int,unsigned,long,v1,v2
From: https://www.cnblogs.com/dijah/p/18286677