0%

思路讲解

思路就是根号分治

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
FOR(_,1,Q){
ll op,a,b,c;
cin>>op;
if(op==0){
cin>>a>>b>>c;
ll ida=upper_bound(L+1,L+1+idx,a)-L;
ida-=1;
ll idb=upper_bound(L+1,L+1+idx,b)-L;
idb-=1;
ll ans=0;
FOR(i,0,SZ(g[ida])-1){
if(g[ida][i][1]>=a && g[ida][i][1]<=b && g[ida][i][0]>=c){
++ans;
}
}
if(ida!=idb){ // 注意这个地方,小心相同重复统计导致WA
FOR(i,0,SZ(g[idb])-1){
if(g[idb][i][1]>=a && g[idb][i][1]<=b && g[idb][i][0]>=c){
++ans;
}
}
}
FOR(i,ida+1,idb-1){
ll id=lower_bound(all(g[i]),(arr2){c,0})-g[i].begin();
ans+=SZ(g[i])-id;
}
cout<<ans<<"\n";
}else{
cin>>a>>b;
ll id=upper_bound(L+1,L+1+idx,a)-L;
id-=1;
FOR(i,0,SZ(g[id])-1){
if(g[id][i][1]==a){
g[id][i][0]=b;
break;
}
}
sort(all(g[id]));
}
}

如果问小于等于c的可以这么写。

1
2
3
4
FOR(i,ida+1,idb-1){
ll id=upper_bound(all(g[i]),(arr2){c,INF})-g[i].begin();
ans+=id;
}

AC代码

https://www.luogu.com.cn/record/220963190

https://www.luogu.com.cn/record/220973015 双倍经验,SP3261 RACETIME - Race Against Time

https://www.luogu.com.cn/record/220977711 三倍经验,UVA12003 Array Transformer

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

思路讲解

一般来说,这种绿题图论建模都是有套路的,一般来说就是在一个联通图内匹配符合一些性质(可能匹配数量直接和V和E相关,也有可能跑一个dfs就出来了)。

我仔细看了一下,感觉可以转化为无向图边的重定向问题 CF-1021-D. Baggage Claim

这些是整段代码最重要的部分。其实这部分成立的原因是该子图是联通的(虽然是废话)。

那么我们可以想到一种构造方式,就是从*点(完美匹配点,若没有就从双边点向外延伸,若还没有就无所谓了)出发,然后定向,形成像树一样的形状。

image

1
2
3
4
5
ll size=fa.size(i);
ll edge=fa.edge[fa.find(i)];
ll mcc=fa.mcc[fa.find(i)];
// 现在这里的ans意思是我可以白嫖多少元素
ans+=2*mcc+min(edge,size-mcc);

AC代码

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

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

WA https://www.codechef.com/viewsolution/1167153030

就是贪心做法,优先处理比较独特的。

显然会被相等的一些hack数据hack

1
2
3
4
5
1
3
1 3 2 3 1 2

3

思路讲解

hard版,这个题解中的每句话都值得细细品味。至少每个段落都得看,都得学。

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

AC代码

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

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

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

EZ不小心错了一次,实际上是INF开小了。

第186行这里容易符号写反。

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

1
if(mid!=N+1-cnt[2])res=tr[1].findk(mid)-mid-tr[2].findk(N+2-mid)+(N+2-mid);

思路讲解

ll l=mxA,r=4e9;

这个不要开太大,因为这个r是有可能达到r*N的级别的,最好不要大于1e14。

https://www.codechef.com/viewsolution/1167128227 这个提交就是ll overflow 了。

那么这个r的确定那,可以这样想,就是你不要去想极端情况,可以想一种不是最优解,但是比较平均的做法,比如说这道题 r=mxa+(sumb+N)/Nr=mxa+(sumb+N)/N 这样就比较好。

其实这道题目用二分还是比较明显的,最大的最小

AC代码

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

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

思路讲解

求解右边第一个大于自己的数的下标。

AC代码

https://www.luogu.com.cn/record/220790487

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