0%

思路讲解

是比较简单的树上dp问题,记录一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void dfs(ll node,ll x0,ll x1,ll cnt){
// x0表示cnt%2==0时加
if(vis[node]) return;
vis[node]=true;
ans[node]= cnt%2==0?A[node]+x1:A[node]+x0;
if(cnt%2==0){
x0-=A[node];
x1+=A[node];
}
if(cnt%2==1){
x0+=A[node];
x1-=A[node];
}
FOR(i,0,SZ(g[node])-1){
ll lnode=g[node][i];
if(vis[lnode]) continue;
dfs(lnode,max(0ll,x0),max(0ll,x1),cnt+1);
}
}

AC代码

https://codeforces.com/contest/2114/submission/323228554

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

思路讲解

感觉每次选择都可能有后效性怎么办?

1
2
3
// 碰到b,a   c,a operate 在最近的位置
// a,b a,c not operate
// b,c c,b operate or not?

仔细一想那,这道题目也没有那么复杂其实,其实只有b,c是需要考虑是否操作的。

只考虑那么一种情况的话,其实就看后面有没有c,a,而且b的前面c的数量啦。

https://www.cnblogs.com/fwdzh/p/18909502

这个题解告诉我们,我们是不可能在线处理的,这个难度是比较大的,但是我前面一直在想这个(QAQ)。

AC代码

https://codeforces.com/contest/2111/submission/322930903

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

那么我们发现,匹配应该是这样匹配,而不是用最大的匹配最小的。

1
2
3
4
5
6
7
if(*g[idx2].begin()<*g[idx3].rbegin()){
// g[idx2].pop_front();
auto it=g[idx3].lower_bound(*g[idx2].begin());
g[idx2].erase(g[idx2].begin());
g[idx3].erase(it);
s[i]='a';
}

思路讲解

这道D题确实不算太难,我赛时应该也是可以写出来的。

采用类似于下图的构造方式即可

image

AC代码

https://codeforces.com/contest/2111/submission/322856069

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

思路讲解

https://www.luogu.com.cn/article/rae0b6wl

总体思路就是将等于目标转变为构造最小的 大于等于目标的构造

1
2
3
4
5
6
ROF(i,Q,1){
ll x=Op[i][0],y=Op[i][1],z=Op[i][2];
C[x]=max(C[x],C[z]);
C[y]=max(C[y],C[z]);
if(x!=z && y!=z) C[z]=0;
}

既然是要被覆盖的,我们还要构造最小的吗,所以我们令

AC代码

https://codeforces.com/contest/2115/submission/323143930

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

https://codeforces.com/contest/2115/submission/322643402

比最大条件小的点是不被允许的,那么填什么最好呢?

https://codeforces.com/contest/2115/submission/322665243

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
10 10
4 3 8 4 2 4 4 4 4 2
9 6 8
7 1 4
2 5 5
8 1 8
7 4 6
9 7 8
6 8 8
8 4 5
9 10 5
3 1 9

附随机数据生成器

https://www.cnblogs.com/cjcf/p/18906536

给出最后的结果和操作步骤,求初始数组

通过贪心,我们发现在A[x]有多条边的时候,只能选择满足最大的边(条件,边权为A[z]大小)

比最大条件小的点是不被允许的,那么我们就要看是就选这个最大条件还是选自己的值(如果自己的值比最大条件大)。

贪心的来说,如果自己的值是要被覆盖的,那么肯定选条件值,如果不被覆盖,那肯定就选自己的值。

当然,上面的这些只针对于不是多重覆盖的情况,如果出现多重覆盖情况,那么只保留最后覆盖情况(前面覆盖了也是白覆盖)。

那么我们发现,我们小瞧了这道题目,就是说操作之间是有可能互相影响的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
10 10
4 3 8 4 2 4 4 4 4 2
9 6 8
7 1 4
2 5 5
8 1 8
7 4 6
9 7 8
6 8 8
8 4 5
9 10 5
3 1 9

当然,我们发现我们的贪心结论是没有什么大的问题的,只是适用范围错了,其仅在倒推时,不涉及传递的时候有用。

思路讲解

https://www.luogu.com.cn/article/63o898db

如果说一个序列是1,2,3,4,5,……,N,还有一个序列无序,那么其实就选一个LIS就行。

那么现在前面这个序列不是有序的,但前面这个序列的标号是有序的,这个时候怎么搞?其实我们就定义新的顺序为A[1]<A[2]<A[3]……<A[N],就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
scanf("%lld",&N);
FOR(i,1,N) {scanf("%lld",&A[i]);posA[A[i]]=i;}
FOR(i,1,N) {scanf("%lld",&B[i]);}
vector<ll> dp;
FOR(i,1,N){
if(dp.empty()) dp.pb(posA[B[i]]);
else{
vector<ll>::iterator it=lower_bound(all(dp),posA[B[i]]);
if(it==dp.end()) dp.pb(posA[B[i]]);
else dp[it-dp.begin()]=posA[B[i]];
}
}
printf("%d\n",SZ(dp));

AC代码

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

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