XJOI一句话复习题解

距NOIP还有4天,一天复习5个contest, 计划复习完
Contest 62 今天刚做,所以就…嘿嘿嘿

T1 考虑一下实际意义,每次数一条斜率上点数,覆盖所有斜率,所以是n*m,cxt莫比乌斯反演.
T2 dfs序优化DP,暴力可过
T3 暴力可过,是一道决策单调性的问题,状态比较新颖,下次遇到中位数题,试试以中间点为状态的Dp

contest 7

T1 大模拟 substr 与 find 的stl大法
T2 给你一个带权值的环,让你选出m个数两两不相邻,使得权值和最大. 我们考虑维护一个堆,用堆做这类阶段性问题 1:用指针扫2 :用链表方便撤销.
我们加入一个元素就把它和左右两边的空元素打包,算出取反贡献,再加入堆,这样每次增加一个元素,且支持撤销,保证最优. 比较经典
T3:瓶颈生成树

contest 9

T1 暴力模拟权值不超过9*18*1000
T2 倍增预处理 + 最短路
T3 像圆括号匹配,不断地把1001变成0,原串必定仍然合法.

contest10

T1 游戏策略DP
T2 大模拟,貌似可以用度数,每个点满了6度才会换下一个点,模拟优化
T3 前缀

contest 11

T1树上查分
T2矩阵快速幂
T3 转图论二分图偶环 , 然后同构就相同,放苹果即可

contest 12

T1 前缀和
T2 状压DP 记录第i时间,第j位置已钓哪些鱼,为状态暴力转移
T3 计算几何暴力判断投射阴影的位置,然后从下往上做,剪掉被覆盖的部分.左右都做一遍,因为左右都可能被照到
T4 按照出现次数从大到小分配给从小到大疲劳的手指

contest 13

T1 想象成边界无穷大,一个交点外角多360度,一条线外角多360度
T2 快速幂
T3 四维DP 记录各根杆的长度,暴力转移. 16 * 60^3 , 我当时状压DP记录选哪些,是否能拼出对边..

contest 14

T1 按mod4分类讨论 BFS
T2 枚举路线暴力最短路转移
T3 毒题 化成 (x-n!)*(y-n!)=(n!)^2然后通过数(n!)^2的约数个数来计算.

contest 15

T1 每相邻两座山峰在某一特定值之后取前一座优,否则取后一座优,我们可以维护一个单调队列然后在上面二分,或者离线排完序O(n)算
T2 bitset 优化四维偏序 O(n^2/32)
T3不会

contest 16

T1 关键路径注意字典序要反着跑遍记pre
T2 树形Dp + Size 优化
T3 状压Dp

contest 17

T1 找规律, 用树状数组维护,这类题一看也只能这么做
T2 二叉树dp[i][j][k] 表示size为i的子树,有j对匹配,根是否选了的方案数,暴力转移
T3 维护一个生成森林,然后对每一条询问边,用并查集维护同一个中的Size,这类题的套路

contest 18

T1 hash+边界特判
T2 暴力DP
T3 模意义最短路

contest 19

T1 模拟
T2 推式子相似三角形+暴力
T3 十分巧妙的最短路建图 先跑了一遍最短路去掉了很多冗余的边. (hard)

contest 20

T1 数学题,二分图转化加数学归纳法
T2 对于每一个联通块搜出一棵树,很显然你可以走gcd的两倍,可以证明只需要考虑环和树边上的走来走去就能组合出所有情况,这样我们就知道了我们可以增减的最小幅度,这样就可以O(gcd)算了,
T3 前缀和(容斥) 或 线段树

contest 21

T1 概率Dp 不会
T2 数学题推式子 杜教筛 ()
T3 数位DP

contest 22

T1 暴力
T2 Dp
T3 瓶颈生成树

contest 23

T1 Dp
T2 十分恶心的数学式子(带坑)
T3 推个式子转化搞逆元即可

contest 25

T1 二分答案+前缀最值
T2 k度限制最小生成树模板
T3 大力分类讨论的题

contest 26

T1 高精度
T2 缩完点之后找树的直径染色,证明一定最优
T3 单调性+贪心

contest 27

T1 暴力
T2 字典树转成两次询问
T3 状压DP

contest 28

T1 树状数组
T2 暴力状压最短路
T3 扫描线优化至 n^2logn

contest 29

T1 暴力枚举天数DP转移
T2 暴力dfs题目没看清楚系列
T3 很神的分块+链表
先一遍DP出 <= 2 * Size 的答案
剩下利用链表搞 利用r的单调性从右往左删除,一边暴力左边<=sqrt(n)的块统计答案

contest 30

T1 大力DP 卡空间…
T2 找规律mod4意义下分别维护最大值
T3 并查集按dfs深度向上合并的模板题,用并查集维护联通块的神题.(易错:merge要先跳到fa)

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;

const int N = 1e5 + 5;
const int M = N * 2;

int f1[N] , f2[N] , s1[N] , s2[N] ,  s3[N] , n , m  , t , fir[N] , ne[M] , to[M] , cnt , dep[N] , u , v , p , q , val[N] , w , C[M] , fa[N];

void add(int x , int y , int z) {
    ne[++ cnt] = fir[x];  fir[x] = cnt; to[cnt] = y; C[cnt] = z;
}

void link(int x , int y , int z) {
    add(x , y , z); add(y , x , z);
}

#define Foreachson(i , x) for(int i = fir[x];i;i = ne[i])

int getf1(int x) {
    return (f1[x] == x) ? x : (f1[x] = getf1(f1[x]));
}

int getf2(int x) {
    return (f2[x] == x) ? x : (f2[x] = getf2(f2[x]));
}

void merge1(int x , int y) {
    x = getf1(x); y = getf1(y);
    f1[getf1(y)] = x;
    s1[x] += s1[y];
    s3[x] += s3[y];
}

void merge2(int x , int y) {
    x = getf2(x); y = getf2(y);
    f2[getf2(y)] = x;
    s2[x] += s2[y];
}

void dfs(int x , int f) {
    dep[x] = dep[f] + 1; fa[x] = f;
    Foreachson(i , x) {
        int V = to[i]; if(V == f) continue;
        dfs(V , x);
        val[V] = C[i];
        if(val[V] <= 1) merge1(x , V);
        if(val[V] <= 2) merge2(x , V);
        if(val[V] == 3) {
            s3[x] += s2[getf2(V)];
        }
    }
}

int main(void) {
    scanf("%d%d", &n , &t);
    for(int i = 1;i < n;i ++) {
        scanf("%d%d%d" , &u , &v ,&w); link(u , v , w);
    }
    for(int i = 1;i <= n;i ++) f1[i] = f2[i] = i , s1[i] = s2[i] = 1;
    dfs(1 , 0);
    for(;t--;) {
        scanf("%d%d%d%d" , &u , &v , &p , &q);
        if(dep[u] < dep[v]) swap(u , v);
        val[u] --;
        if(val[u] == 1) {
            merge1(v , u);
        }
        else if(val[u] == 2) {
            merge2(v , u); //merge先跳上去 
            s3[getf1(v)] -= s2[u];
            s3[getf1(fa[getf2(v)])] += s2[u];
        }
        int fx = getf2(p) , fy = getf2(q);
        int flag = (fx == fy);
        if(!flag) {
            int fp = getf1(p) , fq = getf2(q);
            if(dep[fp] < dep[fq]) {
                flag = (getf1(fa[fq]) == fp);
            }
            else {
                flag = (getf2(fa[fp]) == fq);
            }
        }
        printf("%d " , flag);
        int res = s2[getf2(p)] + s3[getf1(p)];
        if(val[getf1(p)] == 3) res += s2[getf2(fa[getf1(p)])];
        printf("%d\n" , res);
    }
}

contest 31

T1 暴力
T2 最短路 特殊处理k=0的边
T3 暴力概率DP

contest 32

T1 贪心
T2 分段DP
T3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值