题目链接:Codeforces Round #504 (Div. 1 + Div. 2)
A:很重要的一点,只有一个 ‘*’ ,所以我们先用两边的去匹配,最后考虑剩下的即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int n,m,flag; char a[N],b[N];
signed main(){
cin>>n>>m; scanf("%s %s",a+1,b+1);
for(int i=1;i<=n;i++) if(a[i]=='*') flag=i;
if(!flag&&strcmp(a+1,b+1)) return puts("NO"),0;
if(!flag&&strcmp(a+1,b+1)) return puts("YES"),0;
for(int i=1;i<=flag-1;i++){
if(a[i]!=b[i]) return puts("NO"),0;
}
for(int i=n,j=m;i>flag;i--,j--){
if(j<flag||a[i]!=b[j]) return puts("NO"),0;
}
puts("YES");
return 0;
}
B:先考虑n,k的大小,然后我们可以找到可以用的数字的上下界,然后除以二即为答案。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k,res;
signed main(){
cin>>n>>k;
if(n>=k){
cout<<(k-1)/2<<endl;
}else{
if(n+n-1<k) cout<<0<<endl;
else{
int low=k-n; int num=n-low+1;
cout<<num/2<<endl;
}
}
return 0;
}
C:相当于就是删除一些合法序列,所以用栈维护即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
int n,k,num; string str; stack<char> st; vector<char> v;
signed main(){
cin>>n>>k>>str; num=n-k;
for(int i=0;i<str.size();i++){
if(!st.size()||!num) st.push(str[i]);
else{
if(st.top()=='('&&str[i]==')') st.pop(),num-=2;
else st.push(str[i]);
}
}
while(st.size()) v.push_back(st.top()),st.pop();
reverse(v.begin(),v.end());
for(int i=0;i<v.size();i++) cout<<v[i];
return 0;
}
D:我们可发现,如果某个数字的开头和结尾直接有比这个数字小的数字一定不合法,否则一定合法。用线段树或者ST表维护一下即可。
最后0的地方直接放相邻的数字即可,注意q这个数字一定存在,如果不存在也不合法。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10,inf=0x3f3f3f3f;
int n,q,a[N],l[N],r[N],res[N],cnt,flag;
int mi[N<<2];
void build(int p,int l,int r){
if(l==r){mi[p]=a[l]; return;}
int mid=l+r>>1;
build(p<<1,l,mid); build(p<<1|1,mid+1,r);
mi[p]=min(mi[p<<1],mi[p<<1|1]);
}
int ask(int p,int l,int r,int ql,int qr){
if(l==ql&&r==qr) return mi[p];
int mid=l+r>>1;
if(qr<=mid) return ask(p<<1,l,mid,ql,qr);
else if(ql>mid) return ask(p<<1|1,mid+1,r,ql,qr);
else return min(ask(p<<1,l,mid,ql,mid),ask(p<<1|1,mid+1,r,mid+1,qr));
}
signed main(){
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) if(!a[i]) a[i]=inf;
for(int i=1;i<=n;i++) if(a[i]==inf) cnt++;
if(cnt==n){
puts("YES");
for(int i=1;i<=n;i++) printf("%d ",q); return 0;
}
build(1,1,n); memset(l,0x3f,sizeof l);
for(int i=1;i<=n;i++){
if(a[i]==inf) continue;
l[a[i]]=min(l[a[i]],i); r[a[i]]=max(r[a[i]],i);
}
for(int i=1;i<=q;i++){
if(l[i]==inf) continue;
if(ask(1,1,n,l[i],r[i])<i) return puts("NO"),0;
}
if(!cnt){
for(int i=1;i<=n;i++) if(a[i]==q) flag++;
if(!flag) return puts("NO"),0; puts("YES");
for(int i=1;i<=n;i++) printf("%d ",a[i]); return 0;
}
puts("YES");
for(int i=1;i<=n;i++) if(a[i]==q) flag=1;
if(!flag){
for(int i=1;i<=n;i++) if(a[i]==inf){
a[i]=q; break;
}
}
for(int i=2;i<=n;i++) if(a[i]==inf) a[i]=a[i-1];
for(int i=n-1;i>=1;i--) if(a[i]==inf) a[i]=a[i+1];
for(int i=1;i<=n;i++) printf("%d ",a[i]);
return 0;
}
F:树剖维护MST即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6+10,inf=0x3f3f3f3f;
int n,k,m,w[N],g[N],a[N],b[N],c[N],idx;
int pos[N],bl[N],f[N],son[N],h[N],sz[N],cnt;
int mi[N],lazy[N];
int head[N],nex[N<<1],to[N<<1],tot;
inline void ade(int a,int b){to[++tot]=b; nex[tot]=head[a]; head[a]=tot;}
inline void add(int a,int b){ade(a,b); ade(b,a);}
int find(int x){return x==g[x]?x:g[x]=find(g[x]);}
void dfs1(int x){
sz[x]=1;
for(int i=head[x];i;i=nex[i]){
if(f[x]==to[i]) continue;
f[to[i]]=x; h[to[i]]=h[x]+1;
dfs1(to[i]); sz[x]+=sz[to[i]];
if(sz[to[i]]>sz[son[x]]) son[x]=to[i];
}
}
void dfs2(int x,int belong){
pos[x]=++cnt,bl[x]=belong;
if(!son[x]) return ; dfs2(son[x],belong);
for(int i=head[x];i;i=nex[i])
if(h[to[i]]>h[x]&&to[i]!=son[x]) dfs2(to[i],to[i]);
}
inline void push_down(int p){
if(lazy[p]){
if(lazy[p]<mi[p<<1]) mi[p<<1]=lazy[p<<1]=lazy[p];
if(lazy[p]<mi[p<<1|1]) mi[p<<1|1]=lazy[p<<1|1]=lazy[p];
lazy[p]=0;
}
}
void change(int p,int l,int r,int ql,int qr,int v){
if(ql==l&&r==qr){if(v<mi[p]) mi[p]=lazy[p]=v; return;}
int mid=l+r>>1; push_down(p);
if(qr<=mid) change(p<<1,l,mid,ql,qr,v);
else if(ql>mid) change(p<<1|1,mid+1,r,ql,qr,v);
else change(p<<1,l,mid,ql,mid,v),change(p<<1|1,mid+1,r,mid+1,qr,v);
}
int ask(int p,int l,int r,int x){
if(l==r) return mi[p];
int mid=l+r>>1; push_down(p);
if(x<=mid) return ask(p<<1,l,mid,x);
else return ask(p<<1|1,mid+1,r,x);
}
inline updata(int x,int y,int v){
while(bl[x]!=bl[y]){
if(h[bl[x]]<h[bl[y]]) swap(x,y);
change(1,1,idx,pos[bl[x]],pos[x],v); x=f[bl[x]];
}
if(pos[x]>pos[y]) swap(x,y);
change(1,1,idx,pos[x],pos[y],v);
}
signed main(){
ios::sync_with_stdio(false); cin.tie(nullptr);
cin>>n>>k>>m; memset(mi,0x3f,sizeof mi);
for(int i=1;i<=n;i++) g[i]=i; idx=n;
for(int i=1,x,y;i<=k;i++){
cin>>x>>y;
add(x,idx),add(idx,y); g[find(x)]=find(y);
}
for(int i=1;i<=m;i++){
cin>>a[i]>>b[i]>>c[i];
int x=find(a[i]),y=find(b[i]);
if(x!=y) g[x]=y,add(a[i],b[i]);
}
dfs1(1); dfs2(1,1);
for(int i=1;i<=m;i++) updata(a[i],b[i],c[i]);
long long res=0;
for(int i=1;i<=k;i++){
int now=i+n,val=ask(1,1,idx,pos[now]);
if(val==inf){puts("-1"); return 0;}
res+=val;
}
cout<<res;
return 0;
}