0%

思路讲解

使用分块以及分块思想,考虑一个未定义元素块。

https://www.codechef.com/problems/BLOCKSTR?tab=solution

那么我们这个为什么可以ans-=2?

1
....01????10.....

这种情况自然不必多说,那么确实是实打实的减少了2个块。

1
.....11??????11?????11......

那么我们的疑惑是这种情况下-2,-2可以吗?答案当然是可以的,这里的“?”全部变为1了以后总块数就是1了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
sort(all(cnts[0]));
sort(all(cnts[1]),greater<ll>());
sort(all(cnts[2]),greater<ll>());
ll ans=oans;
vector<bool> alde(N+5,false);
FOR(i,0,N){
if(i<cnt1){
cout<<-1<<" ";
continue;
}
if(i>N-cnt0){
cout<<-1<<" ";
continue;
}
if(i==cnt1){
cout<<ans<<" ";
continue;
}
if(!cnts[2].empty()){ // 1 1
ll id=SZ(cnts[2])-1;
cnts[2][id]--;
if(cnts[2][id]<=0){
cnts[2].pop_back();
ans-=2;
}
cout<<ans<<" ";
continue;
}
if(!cnts[1].empty()){
ll id=SZ(cnts[1])-1;
cnts[1][id]--;
if(cnts[1][id]<=0){
cnts[1].pop_back();
}
cout<<ans<<" ";
continue;
}
if(!cnts[0].empty()){
ll id=SZ(cnts[0])-1;
if(!alde[id]) ans+=2;
cnts[0][id]--;
alde[id]=true;
if(cnts[0][id]<=0){
cnts[0].pop_back();
}
cout<<ans<<" ";
continue;
}
}

AC代码

https://www.codechef.com/viewsolution/1168370649

心路历程(WA,TLE,MLE……)

这个0???0的这个块的排序要反过来,因为我们需要他更持久一点,因为他毕竟是要ans+=2的。

1
sort(all(cnts[0]));

思路讲解

two number <=L || >=R delete

1
2
3
4
5
6
7
8
9
10
11
12
13
FOR(i,1,Q){
// two number <=L || >=R delete
cin>>L[i]>>R[i];
if(L[i]==R[i]){
cout<<0<<"\n";
continue;
}
ll lans=ans;
lans-=ansp.query(R[i],N);
lans-=anss.query(1,L[i]);
if(lans<0) cout<<"0\n";
else cout<<lans<<"\n";
}

AC代码

https://www.codechef.com/viewsolution/1168087702

心路历程(WA,TLE,MLE……)

那么就是要注意这个特判

1
2
3
4
if(L[i]==R[i]){
cout<<0<<"\n";
continue;
}

思路讲解

那么注意到入度为2才是这个修改的充要条件,因为这样子修改边的朝向保证了只会增加一个好对数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
auto dfs=[&](auto &&dfs,ll u,ll alte)->void{
vis[u]=true;
FOR(i,0,SZ(g[u])-1){
ll v=g[u][i];
if(vis[v]) continue;
bool isop=false;
// 那么注意到入度为2才是这个修改的充要条件
if(SZ(g[u])==2 && isM==false){
alte=1-alte;
if(alte){
ans.pb({v,u});
}else{
ans.pb({u,v});
}
isM=true;
isop=true;
}else{
if(alte){
ans.pb({v,u});
}else{
ans.pb({u,v});
}
}
dfs(dfs,v,1-alte);
if(isop) alte=1-alte;
}
};

AC代码

https://codeforces.com/contest/2112/submission/325852721

心路历程(WA,TLE,MLE……)

思路讲解

简单来说,就是第一次炸了以后还能存活下来的金块,一定能活下来。

那么形式化的理解就是说第一次炸完以后,剩下的空间就足够其他炸弹进行一些精细操作了。

然后枚举+二维前缀和,就可以用二维前缀和来求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FOR(i,1,N){
FOR(j,1,M){
Sum[i][j]=Sum[i-1][j]+Sum[i][j-1]+(G[i][j]=='g')-Sum[i-1][j-1];
}
}
ll ans=0;
FOR(i,1,N){
FOR(j,1,M){
if(G[i][j]=='.'){
ll xl=max(i-K+1,1ll),xr=min(i+K-1,N),yl=max(1ll,j-K+1),yr=min(M,j+K-1);
ll lans=Sum[xr][yr]+Sum[xl-1][yl-1]-Sum[xl-1][yr]-Sum[xr][yl-1];
ans=max(ans,Sum[N][M]-lans);
}
}
}

AC代码

https://codeforces.com/contest/2113/submission/325681423

心路历程(WA,TLE,MLE……)