• 2019西安邀请赛


    A Tasks

    实况

    一开始非常居然想DP(反动思想),然后队友说拍个序就好了.

    题解

    从小到大排序,贪心选小的,直到不能选为止.

    C Angel's Journey

    实况

    一开始输出6位小数,居然wa了,非要输出4位才行.

    题解

    如果终点在直线x=rx-r的左边,那就从底部一直走到(rx-r,ry).然后走直线直接去终点.

    如果终点在直线x=rx-r的右边,那就从底部一直走到(rx+r,ry).然后走直线直接去终点.

    如果终点在以上两个直线的中间,那就找到终点和圆的切线,从底部走到切点,然后走直线去终点.

    距离是

    [d = sqrt{(rx-x)^2+(ry-y)^2}\ l = sqrt{d^2+r^2}\ l2 = min(sqrt{((rx-r)-x)^2+(ry-y)^2}, sqrt{((rx+r)-x)^2+(ry-y)^2})\ alpha = arccosleft(frac{r*r+d*d-l*l}{2*r*d} ight)\ eta=arccosleft(frac{r*r+d*d-l2*l2}{2*r*d} ight)\ ans = frac{2pi r}{4}+(eta-alpha)*r+l ]

    D Miku and Generals

    实况

    我把给的点简化成了若干个pair,队友写了一个dp.

    因为存pair的vector没有清空,re一发.

    题解

    先把数字/100,方便使用.

    把互相关联的数字连接起来,然后涂色,每个联通块可以得到两个数字,

    分别代表这个联通块的第一个点给A时,A获得的值和B获得的值.

    如果有cnt个联通块,我们就有cnt对这样的数字(自由的数字就是{c[i], 0}).

    然后dp

    dp[i][j]表示只考虑前i对数字,是否可以形成差是j的分配方案

    一开始dp[1...cnt][-1e6..1e6]都赋值成0;

    dp[0][0]赋值成1,表示不考虑任何数字时,可以使差是0.

    然后对于每一对数字for i = 0 to cnt

    对于每一种差for j = -1e6 to 1e6

    如果考虑前i对数字时,可以使差是j,即f[i][j] == 1

    那么如果把这一对数字的前一个分配给A,差就会变成j+i.first-i.second,所以F[i+1][j+i.first-i.second]=1,

    那么如果把这一对数字的前一个分配给B,差就会变成j-i.first+i.second,所以F[i+1][j-i.first+i.second]=1,

    找到最小的差,较大的一个的数值是(所有数字的和-差)/2+差

    E Tree

    实况

    蛐蛐树剖,我起了,一枪秒了

    题解

    树链剖分,用一颗线段树来存链上的数字.

    线段树的每个节点是一个32的数组,数组的值val[rt][i]代表:

    在这个节点代表的区间里,有多少个数字x符合x&(1<<i) != 0,

    • 第一种操作,如果t&(1<<i) != 0 ,那么被修改的区间的val[rt][i]修改为区间的大小,表示区间里的每一个数字这一位都是1;否则无视

    • 第二种操作,如果t&(1<<i) == 0 ,那么被修改的区间的val[rt][i]修改为0,表示区间里的每一个数字这一位都是0;否则无视

    第三种操作,我们求一个数组tmp[1..32],其中tmp[i]为他给的区间的所有节点的val[rt][i]的和.

    然后根据nim博弈,遍历每一位for i = 0 to 30,

    int p = (t&(1<<i))?1:0

    如果某一位tmp[i] + p不是偶数,那么输出YES.

    否则输出NO.

    J And And And

    实况

    只会求一条直链的,

    然后就开始瞎想:启发式合并?树剖?点剖???

    和AC的距离

    完全忘了树上dp....

    题解

    以1为根

    对于一条路径(u,v),如果他的异或和是0, 那么他的贡献应该是u那一端的节点数量*v那一端的节点数量.

    先第一个dfs,算出每一个点的:

    siz[u],代表u的子树大小;

    sum[u],代表每一个点到根节点的路径和异或和.

    如下

    void dfs1(ll u)
    {
        siz[u] = 1;
        for(auto i : g[u])
        {
            ll v = i.first;
            ll w = i.second;
            sum[v] = sum[u] ^ w;
            dfs1(v);
            siz[u] += siz[v];
        }
    }
    
    第二个dfs,统计答案

    可以知道如果两个节点u和v满足sum[u] == sum[v],那么他们之间的路径异或和是0;

    那么他的贡献应该是u那一端的节点数量*v那一端的节点数量.

    用一个map[x,y],y表示当前已经经过的节点里面,每一个符合sum[v]==x的节点v的另一端的节点数量的和.

    所以每当遍历到一个结点map[sum[u]]就表示所有v那一端的节点数量的和.ans += map[sum[u]]*siz[u]

    如下

    void dfs2(int u)
    {
        ans = (ans + siz[u] * m[sum[u]] % mod) % mod;
        for(auto i : g[u])
        {
            ll v = i.first;
            ll w = i.second;
            m[sum[u]] = (m[sum[u]] + n - siz[v] + mod) % mod;
            dfs2(v);
            m[sum[u]] = (m[sum[u]] - n + siz[v] + mod) % mod;
        }
        m[sum[u]] = (m[sum[u]] + siz[u]) % mod;
    }
    

    L Swap

    实况

    通过一种神秘力量(打表),发现了规律

    题解

    轮流执行操作一和操作二就可以产生所有结果,

    然后看数量找规律

    if n==1 : 1

    else if n==2 : 2

    else if n==3 : 6

    else if (n-1)%4 == 0 : n*2

    else if (n%2) != 0 : 12

    else if n%4 == 0 : 4

    else if n%2 == 0 : n

    M Travel

    实况

    dijkstra,上来就wa一发,回头一看输入:额,c是干什么的

    题解

    就是dijkstra,要注意这里dis[x]要存两个数字,lv和剩余次数.

    lv小的更优,如果lv相同,剩余次数多的更优.

    每次找下一步要注意升级和减少剩余次数.

  • 相关阅读:
    Web框架&&django介绍
    bootstrap
    jQuery
    js Bom和Dom
    javascript
    css
    二分查找
    php常用函数
    基于laravel自定义测试组件
    Document
  • 原文地址:https://www.cnblogs.com/zzidun-pavo/p/13793324.html
Copyright © 2020-2023  润新知