第一周训练

第1周

树形dp:

[POI2013] LUK-Triumphal arch - 洛谷

[USACO08JAN] Cell Phone Network G - 洛谷 //相邻点

战略游戏 - 洛谷 //覆盖边

[POI2014] HOT-Hotels - 洛谷 //实际上这个是考虑每个节点,根据每个相邻节点不同分支进行考虑

[USACO17DEC] Barn Painting G - 洛谷 //dp方案数,乘法原理

[HNOI2014] 米特运输 - 洛谷 //这个思路挺巧妙,考虑结果的规律,然后进行筛选,注意哈希冲突。

[蓝桥杯 2021 省 A] 左孩子右兄弟 - 洛谷 dfs即可

[POI2014] FAR-FarmCraft - 洛谷 好题,分类讨论一下,发现贪心选择安装时间长的即可

[蓝桥杯 2018 国 A] 采油 - 洛谷 模拟考虑一下即可,由于可以随便空运于是我们可以考虑

[ZJOI2007] 时态同步 - 洛谷 统计以该节点为根的子树的最大值即可。

[HAOI2009] 毛毛虫 - 洛谷 //树的直径

[POI2011] DYN-Dynamite - 洛谷 //二分+树形dp,转化为最小点集覆盖

[USACO12FEB] Nearby Cows G - 洛谷 //两遍dfs,第一遍预处理,第二遍计算结果

四边形不等式优化DP

石子合并(弱化版) - 洛谷 //石子合并+四边形不等式优化

2-SAT:

将或问题转化为 必然后续问题;

下面有几个点需要知道:

1.同一条链必然存在反链;所以如果a同时取0和1,那么将在同一个联通块中;

2.选择某条链的点,其后续节点一定选上;这个后续节点都选上实际上是拓扑排序的体现;

【模板】2-SAT - 洛谷

SAT模版:

 #include<iostream>
 #include<cstring>
 using namespace std;
 const int N=2*1e6+10;
 int h[N], e[N], ne[N], idx; //邻接表
 int dnf[N],stak[N];
 bool instak[N];
 int low[N],id[N],cnt;
 int times;
 int top;
 void add(int a, int b) //添加边
 {
     e[idx] = b, ne[idx] = h[a], h[a] = idx++;
 }
 void tarjan(int u){
     dnf[u]=low[u]=++times;
     instak[u]=true;
     stak[++top]=u;
     for(int i=h[u]; ~i; i=ne[i]){
         int v=e[i];
         if(!dnf[v]){
             tarjan(v);
             low[u]=min(low[u],low[v]);
         }
         else if(instak[v]){
             low[u]=min(low[u],dnf[v]);
         }
     }
     if(dnf[u]==low[u]){
         ++cnt;
         int y;
         do{
             y=stak[top--];
             instak[y]=false;
             id[y]=cnt;
             
         }while(y!=u);
     }
 }
 ​
 int main(){
     std::ios::sync_with_stdio(false);
     cin.tie(0); 
     cout.tie(0);
 ​
     int n,m;
     cin>>n>>m;
     memset(h,-1,sizeof h);
     while(m--){
         int i,j,a,b;
         cin>>i>>a>>j>>b;
         i--;j--;
         add(2*i+!a,2*j+b);
         add(2*j+!b,2*i+a);
     }
      for(int i=0; i<2*n; i+=2){
          if(!dnf[i+1]){
             tarjan(1+i);
          }
          if(!dnf[i]){
             tarjan(i);
          }
      }
      for(int i=0; i<n; i++){
          if(id[2*i]==id[2*i+1]){
              cout<<"IMPOSSIBLE"<<endl;
              return 0;
          }
      }
      cout<<"POSSIBLE"<<endl;
      for(int i=0; i<n; i++){
          if(id[2*i]<id[2*i+1])cout<<"0"<<' ';
          else cout<<"1"<<' ';
      }
      return 0;
 }

tarjian

关于讨论为什么是 low[u]=min(low[u],dnf[v]);

而不是 low[u]=min(low[u],low[v]);

https://www.luogu.com/article/g5rh9ro2

981div3(切6题)

https://codeforces.com/contest/2033/problem/A //模拟即可

https://codeforces.com/contest/2033/problem/B //注意到只需要主对角线,记录主对角线的最小值即可

https://codeforces.com/contest/2033/problem/C //注意到对称的关系,当不相等时交换有效,对于i-1,如果存在贡献就切断,同时swap,将这个swap的影响给到i+1,因为当i和i+1同时调换时,相当于原本的关系。最后影响传递到中间的值。

https://codeforces.com/contest/2033/problem/D //贪心求出能选i就选i,线性处理即可

https://codeforces.com/contest/2033/problem/E //注意到交换两个数最多使得4个数不再处理;然后根据数与数之间的一一对应关系,可以知道直接交换即可;

F不太清楚结论,裴波拉契序列k倍数循环;

https://codeforces.com/contest/2033/problem/G //一开始以为向下走消耗体力,用了离线查询+两颗线段树查询区间最大值;

后面发现是向上走消耗体力,还是离线+线段树维护最大值;nlogn的复杂度

982div2(5题);

https://codeforces.com/contest/2027/problem/A //贪心放在第一个

https://codeforces.com/contest/2027/problem/B //找到比i大的数的个数+i;

https://codeforces.com/contest/2027/problem/C //c并查集不可行;考虑从大到小排序,然后进行连通性转移;

https://codeforces.com/contest/2027/problem/D1 //dp[i]表示前i个的最小成本

https://codeforces.com/contest/2027/problem/D2 //取模有点难,wa3;

at377(7题)

A - Rearranging ABC //模拟

B - Avoid Rook Attack //枚举

C - Avoid Knight Attack //枚举8个方位,nlogn去重

D - Many Segments 2 //注意到l,r可以,那么l+1,r也可以这个事实;考虑枚举r,然后dp转移

E - Permute K times 2 //注意到一一对应关系,判环即可;

F - Avoid Queen Attack //考虑容斥原理

G - Edit to Match //考虑字典树维护,f数组进行dp

总结:

这周出去三天打了ccsp,有点遗憾,只拿了铜奖;如果没有理解错题意的旋转,就不会被硬控8h,导致上头没有做后面的系统题;

加强训练,注意分配时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值