重庆八中周赛Round#1
b998a3b3-532a-451f-99af-7a0998831c4b

贴贴题解
#include<bits/stdc++.h>
using namespace std;
int n,m;
int s[505][505];
int c=0;
bool f1,f2;
int main(){
//freopen("cover.in","r",stdin);
//freopen("cover.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
string a;
cin>>a;
for(int j=1;j<=m;j++){
s[i][j]=a[j-1]-'0';
if(s[i][j]==0) f2=1;
if(s[i][j]==1) c++;
}
}
for(int i=0;i<=n+1;i++){
s[i][0]=1;
s[i][m+1]=1;
}
for(int i=0;i<=m+1;i++){
s[0][i]=1;
s[n+1][i]=1;
}//边界处理,避免出界
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(s[i][j]==0){
if(s[i+1][j]==0||s[i-1][j]==0||s[i][j+1]==0||s[i][j-1]==0||s[i-1][j-1]==0||s[i-1][j+1]==0||s[i+1][j+1]==0||s[i+1][j-1]==0){
f1=1;
i=n+1;
break;
}
}
}
}//
if(f1){
printf("%d",c);
}
else if(f2){
printf("%d",c-1);
}
else{
printf("%d",c-2);
}
}
考试时,没想到对角时也成立的情况,拿了80pts
小小线段树,岂能难倒我
代码:
#include<bits/stdc++.h>
#define N 500005
using namespace std;
typedef long long ll;
const ll p=998244353;
int n,m;
int typ[N];
ll a[N];
struct tree{
ll sum,mul;
int l,r;
}t[N<<2];
void pushup(int k){
t[k].mul=(t[k<<1].mul*t[k<<1|1].mul)%p;
t[k].sum=(t[k<<1].sum*t[k<<1|1].mul+t[k<<1|1].sum)%p;
}
void build(int k,int l,int r){//建树
t[k].l=l,t[k].r=r;
if(l==r){
if(typ[l]==0){
t[k].mul=a[l];
t[k].sum=0;
}
else {
t[k].mul=1;
t[k].sum=a[l];
}
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build((k<<1)|1,mid+1,r);
pushup(k);
}
void change(int k,int pos,int flag,ll val){//单点修改加法
if(t[k].l==t[k].r){
if(flag==0){
t[k].mul=val;
t[k].sum=0;
}
else {
t[k].mul=1;
t[k].sum=val;
}
return ;
}
int mid=(t[k].l+t[k].r)>>1;
if(pos<=mid)change(k<<1,pos,flag,val);
else change((k<<1)|1,pos,flag,val);
pushup(k);
}
struct st{
ll x1,x2;
};
st getsum(int k,int l,int r){
st an;
an.x1=1,an.x2=0;
if(l<=t[k].l&&t[k].r<=r){
an=((st){t[k].mul,t[k].sum});
return an;
}
int mid=(t[k].l+t[k].r)>>1;
if(mid>=l){
st cc=getsum(k<<1,l,r);
an.x1=(an.x1*cc.x1)%p;
an.x2=(an.x2*cc.x1+cc.x2)%p;
}
if(mid<r){
st cc=getsum(k<<1|1,l,r);
an.x1=(an.x1*cc.x1)%p;
an.x2=(an.x2*cc.x1+cc.x2)%p;
}
return an;
}
int main(){
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%lld",&typ[i],&a[i]);
}
build(1,1,n);
while(m--){
int op,x,y;
ll z;
scanf("%d%d%d%lld",&op,&x,&y,&z);
if(op==0){
change(1,x,y,z);
}
else {
st aa=getsum(1,x,y);
printf("%lld\n",(aa.x1*z+aa.x2)%p);
}
}
}
/*
5 5
0 8
1 5
1 7
1 1
0 8
1 5 5 3
0 2 0 6
0 1 1 2
0 5 1 6
1 1 5 6
*/
思路:
大体上可以知道这道题要用到点双联通分量,
观察样例1:
红色的数字为点的编号,蓝色的为耗用资源;
易知:0,1,2,3 为一个点双;2,4 为一个;2,5 为一个;
2为割点
通过缩点可得下图:
黄色边即为缩点的边,黑色边都忽略;
观察上图可知,若要保证联通至少要占2个叶子(即总的叶子数-1)
所以关键是找叶子,叶子有一个特性:叶子所在的点双只有一个割点;
特判:
整张图若没有割点,那么ans=min(cost[i])
#include <bits/stdc++.h>
#define pb(i) push_back(i)
using namespace std;
typedef long long ll;
const ll N=200005;
ll n,m,cnt=1,tot,c;
ll MAX,MIN=2e16;
ll ans;
ll cost[N];
ll dfn[N],low[N],head[N<<1],mco[N];
bool vis[N];
bool f[N];
stack<ll>s;
vector<ll>sthold[N];
ll pos[N];
struct edge{
ll next,to;
}e[N<<2];
void add(ll from,ll to){
e[++cnt].next=head[from];
e[cnt].to=to;
head[from]=cnt;
}
void tarjan(ll k,ll fa){
dfn[k]=++tot,low[k]=tot;
ll son=0;
s.push(k);
for(ll i=head[k];i;i=e[i].next){
ll v=e[i].to;
if(fa==i) continue;
if(!dfn[v]){
son++;
tarjan(v,i);
low[k]=min(low[k],low[v]);
if(dfn[k]<=low[v]){
c++;
while(!s.empty()&&s.top()!=v){
sthold[c].pb(s.top());
s.pop();
}
sthold[c].pb(v),sthold[c].pb(k);
s.pop();
if(k!=0) vis[k]=1;
}
}
else{
low[k]=min(low[k],dfn[v]);
}
}
if(k==0&&son>1) vis[k]=1;
}
int main() {
freopen("stronghold.in","r",stdin);
freopen("stronghold.out","w",stdout);
scanf("%lld%lld",&n,&m);
for(ll i=0;i<n;i++) {
scanf("%lld",&cost[i]);
MIN=min(cost[i],MIN);
}
for(ll i=1,x,y;i<=m;i++){
scanf("%lld%lld",&x,&y);
add(x,y),add(y,x);
}
tarjan(0,0);
ll o=n-1;
ll sta=2e9;
for(ll i=1;i<=c;i++){
ll cc=0;
ll p;
ll MI=2e15;
for(auto x:sthold[i]){
if(!vis[x]) {
MI=min(MI,cost[x]);
f[x]=1;
}
else p=x,sta=p,cc++;
}
if(MI==2e15) continue;
if(cc==1) {
ans+=MI;
MAX=max(MAX,MI);
}
}
if(sta==2e9) {
printf("%lld\n",MIN);
return 0;
}
printf("%lld\n",ans-MAX);
}
/*
5 8
19 67 35 31 44
0 1
0 2
0 3
1 2
1 3
2 3
2 4
3 4
*/
/*
19
*/
就这样
本文来自博客园,作者:MegaSam,转载请注明原文链接:https://www.cnblogs.com/MegaSamTXL/p/17607135.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】