2023.7.6拷逝
T1
对于区间
首先考虑
再考虑
这样就可以在
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
long long n,t,s[200005],stk[200005],r,ans;char a[200005];
int main(){
freopen("common.in","r",stdin);
freopen("common.out","w",stdout);
scanf("%lld",&t);
while(t--){
scanf("%lld%s",&n,a);
ans=0;s[0]=0;
for(int i=1;i<=n;++i)
ans+=i*(n-i+1);
for(int i=1;i<=n;++i){
if(a[i-1]=='(') s[i]=s[i-1]+1;
else s[i]=s[i-1]-1;
}
sort(s,s+n+1);
long long sum=0;
for(int i=0;i<=n;++i){
ans+=s[i]*i-sum;
sum+=s[i];
}//cout<<ans<<endl;
ans/=2;
r=0;
for(int i=0;i<n;++i){
if(a[i]=='(')
stk[++r]=i+1;
else if(r>0){
ans-=(n-i)*stk[r];//stk[r]~i+1
--r;
}
}
printf("%lld\n",ans);
}
fclose(stdin);fclose(stdout);
return 0;
}
T3
首先有一个性质,任意两个三角形没有公共的部分,因为如果有公共部分一定不如把它们合起来更优。
然后就可以考虑
其中,
然后用线段树维护即可。
#include<iostream>
#include<vector>
#include<cstdio>
#define ll long long
using namespace std;
ll n,k,A,ans,x,y,z,cnt[200005],f[200005];
struct node{
int l,r;ll minn,lazy;
} p[800005];
struct node2{
int x;ll w;
};vector <node2> a[200005];
void build(int u,int l,int r){
p[u].l=l;p[u].r=r;
if(l==r)
return ;
int mid=(l+r)>>1;
build(u<<1,l,mid);build(u<<1|1,mid+1,r);
}
void push_down(int u){
p[u<<1].minn+=p[u].lazy;
p[u<<1|1].minn+=p[u].lazy;
p[u<<1].lazy+=p[u].lazy;
p[u<<1|1].lazy+=p[u].lazy;
p[u].lazy=0;
}
void add(int u,int l,int r,ll w){
if(p[u].l>=l&&p[u].r<=r){
p[u].minn+=w;p[u].lazy+=w;
return ;
}
push_down(u);
int mid=(p[u].l+p[u].r)>>1;
if(mid>=l)
add(u<<1,l,r,w);
if(mid<r)
add(u<<1|1,l,r,w);
p[u].minn=min(p[u<<1].minn,p[u<<1|1].minn);
}
ll ask(int u,int l,int r){
if(p[u].l>=l&&p[u].r<=r)
return p[u].minn;
push_down(u);
int mid=(p[u].l+p[u].r)>>1;ll re=1e18;
if(mid>=l)
re=min(re,ask(u<<1,l,r));
if(mid<r)
re=min(re,ask(u<<1|1,l,r));
return re;
}
int main(){
ans=1e18;
scanf("%lld%lld%lld",&n,&k,&A);
build(1,1,k+2);
for(int i=1;i<=n;++i){
scanf("%lld%lld%lld",&x,&y,&z);
a[y].push_back((node2){x,z});
if(x+y!=k)
cnt[x]+=z;
}
for(int i=0;i<=k;++i){
for(int j=0;j<a[k-i].size();++j)
add(1,1,a[k-i][j].x+1,-a[k-i][j].w);
add(1,1,i+1,cnt[i]);
if(i!=0)
add(1,1,i,A);
f[i]=ask(1,1,i+1);
add(1,i+2,i+2,f[i]);
}
printf("%lld\n",f[k]);
fclose(stdin);fclose(stdout);
return 0;
}
T4
将第1,2个,第3,4个相同的数之间连边;将序列中第1,2个,第3,4个相同的数之间连边。
然后会形成若干个偶数环,对于每个环,让其中的数交替出现在集合1,集合2。
#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
using namespace std;
map <int,int> u;
vector <int> p[400005];
int tot,m,n[400005],x,at[400005];bool vis[400005];
void dfs(int x,int num){
vis[x]=1;
if(!at[x])
at[x]=num;
for(int i=0;i<p[x].size();++i)
if(!vis[p[x][i]])
dfs(p[x][i],num^1);
}
int main(){
scanf("%d",&m);
for(int i=1;i<=m;++i){
scanf("%d",&n[i]);
for(int j=1;j<=n[i];++j){
scanf("%d",&x);
++tot;
if(!(j&1)){
p[tot].push_back(tot-1);
p[tot-1].push_back(tot);
}
if(!u[x])
u[x]=tot;
else{
int tmp=u[x];u.erase(x);
p[tmp].push_back(tot);
p[tot].push_back(tmp);
}
}
}
if(u.size())
printf("NO\n");
else{
printf("YES\n");
for(int i=1;i<=tot;++i)
if(!vis[i])
dfs(i,1);
int tot2=0;
for(int i=1;i<=m;++i){
for(int j=1;j<=n[i];++j){
++tot2;
if(at[tot2]) printf("R");
else printf("L");
}
printf("\n");
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】