2021.8.16考試總結[NOIP模擬41]
阿新 • • 發佈:2021-08-16
T1你相信引力嗎 T2marshland T3party? T4半夜
T1 你相信引力嗎
肯定是單調棧維護。但存在重複值,還是個環,不好搞。
發現取區間時不會越過最大值,因此以最大值為斷點將環斷為序列。在棧裡維護當前棧中有多少個與當前元素相等的元素,小分類討論一下。
最後作為最大值的斷點可以與棧中剩下的每個元素組成點對。
$code:$
1 #include<bits/stdc++.h> 2 #define LL long long 3 using namespace std; 4 const int NN=5e6+5; 5 int n,m,top,mx,h[NN<<1],stk[NN<<1],cnt[NN<<1T1]; 6 LL ans; 7 inline int read(){ 8 int x=0,f=1; char ch=getchar(); 9 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } 10 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } 11 return x*f; 12 } 13 inline void write(LL x,char sp){14 char ch[20]; int len=0; 15 if(x<0){ putchar('-'); x=~x+1; } 16 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x); 17 for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp); 18 } 19 signed main(){ 20 n=read(); 21 for(int i=1;i<=n;i++){ 22 h[i+n]=h[i]=read();23 if(h[i]>h[mx]) mx=i; 24 } 25 for(int i=mx;i<mx+n;i++){ 26 while(top&&stk[top]<h[i]) --top, ++ans; 27 if(stk[top]>h[i]) ++ans; 28 else ans+=cnt[top]+(h[i]!=h[mx]); 29 stk[++top]=h[i]; 30 cnt[top]=(stk[top-1]==h[i])?(cnt[top-1]+1):1; 31 } 32 while(top>2){ 33 if(stk[top]==stk[2]) break; 34 --top; ++ans; 35 } 36 write(ans,'\n'); 37 return 0; 38 }
T2 marshland
範圍$50$,棋盤,帶限制,考慮網路流。
黑白染色,將危險點看作黑點。發現每次覆蓋都將佔據黑點左右中一個白點,上下中一個白點。讓奇偶行白點分列二分圖兩邊即可。
在二分圖兩列點間插黑點,把黑點拆成匯點和出點,中間連費用為危險值的邊。跑“最大費用可行流”即可。
$code:$
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int NN=1e6+10,inf=2e9; 4 int to[NN<<1],nex[NN<<1],head[NN],c[NN<<1],w[NN<<1],idx=1; 5 int s,t,incf[NN],pre[NN],dis[NN],flow,value,ans; 6 int n,m,k,sum,val[55][55]; 7 bool stp[55][55],vis[NN]; 8 inline int id(int x,int y){ return (x-1)*n+y; } 9 inline void link(int a,int b,int x,int y){ to[++idx]=b; nex[idx]=head[a]; head[a]=idx; c[idx]=x; w[idx]=y; } 10 inline void add(int a,int b,int x,int y){ link(a,b,x,y); link(b,a,0,-y); } 11 inline int read(){ 12 int x=0,f=1; char ch=getchar(); 13 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } 14 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } 15 return x*f; 16 } 17 inline void write(int x,char sp){ 18 char ch[20]; int len=0; 19 if(x<0){ putchar('-'); x=~x+1; } 20 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x); 21 for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp); 22 } 23 inline bool SPFA(){ 24 queue<int>q; 25 memset(dis,-0x3f,sizeof(dis)); 26 memset(vis,0,sizeof(vis)); 27 q.push(s); dis[s]=0; incf[s]=inf; vis[s]=1; 28 while(!q.empty()){ 29 int x=q.front(); q.pop(); vis[x]=0; 30 for(int i=head[x];i;i=nex[i]){ 31 if(!c[i]) continue; 32 int v=to[i]; 33 if(dis[v]<dis[x]+w[i]){ 34 dis[v]=dis[x]+w[i]; 35 incf[v]=min(incf[x],c[i]); 36 pre[v]=i; 37 if(!vis[v]) vis[v]=1, q.push(v); 38 } 39 } 40 } 41 return dis[t]>0; 42 } 43 void MCMF(){ 44 while(SPFA()){ 45 int i,x=t; 46 if(flow+incf[t]>m) break; 47 flow+=incf[t]; 48 value=max(value,value+dis[t]*incf[t]); 49 while(x!=s){ 50 i=pre[x]; 51 c[i]-=incf[t]; 52 c[i^1]+=incf[t]; 53 x=to[i^1]; 54 } 55 } 56 } 57 signed main(){ 58 n=read(); m=read(); k=read(); s=(n*n<<1)+1; t=s+1; idx=1; 59 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) val[i][j]=read(), sum+=val[i][j]; 60 for(int i=1;i<=k;i++) stp[read()][read()]=1; 61 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ 62 if(stp[i][j]) continue; 63 if((i+j)&1) add(id(i,j),id(i,j)+n*n,1,val[i][j]); 64 else if(i&1){ 65 add(s,id(i,j),1,0); 66 if(i>1) add(id(i,j),id(i-1,j),1,0); 67 if(i<n) add(id(i,j),id(i+1,j),1,0); 68 if(j>1) add(id(i,j),id(i,j-1),1,0); 69 if(j<n) add(id(i,j),id(i,j+1),1,0); 70 } else{ 71 add(id(i,j),t,1,0); 72 if(i>1) add(id(i-1,j)+n*n,id(i,j),1,0); 73 if(i<n) add(id(i+1,j)+n*n,id(i,j),1,0); 74 if(j>1) add(id(i,j-1)+n*n,id(i,j),1,0); 75 if(j<n) add(id(i,j+1)+n*n,id(i,j),1,0); 76 } 77 } 78 ans=sum; MCMF(); 79 write(ans-value,'\n'); 80 return 0; 81 }T2
T3 party?
暴力可以網路流,但我太laji。。