1. 程式人生 > 其它 >2021.8.16考試總結[NOIP模擬41]

2021.8.16考試總結[NOIP模擬41]

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<<1
]; 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 }
T1

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。。