zoukankan      html  css  js  c++  java
  • 7.5总结

    7.5总结

    得分情况

    估分:100+5+0=105

    实际:25+5+0=30

    Rank58??

    第一题打挂了??

    T1

    题目大意

    阿狸和桃子养了n 个小阿狸, 小阿狸们每天都在一起玩的很开心. 作为工程师的阿狸在对小阿狸们之间的关系进行研究以后发现了小阿狸的人际关系由某种神奇的相互作用决定, 阿狸称之为“键”. 每个键有一个频率, 称为键频率, 是一个整数(单位Hz)。

    由于小阿狸们每天成集团地黏在一起, 桃子希望他们能够分成更加独立的几团. 阿狸发现, 一旦小阿狸们分开, 独立的一块连在一起的几个小阿狸就会形成一个家族, 而家族的类型由这个家族的小阿狸的数量唯一确定(比如说只有一个小阿狸的家族显然就是单身码农, 两个小阿狸的显然是一对小阿狸恋人, 三个小阿狸的就是三口之家等等). 显然, 一个小阿狸和另一个小阿狸处于同一家族,当且仅当两个小阿狸之间存在直接或间接的键组成的路径.。

    桃子对每种小阿狸家族都有自己的喜好程度, 她希望所有的小阿狸家族喜好程度之和大于等于K。

    为了让小阿狸们分开来, 阿狸决定让某些键断裂, 只保留某一段频率的键,比如说100Hz 到140Hz 频率的键, 这时频段宽度为40Hz. 当然, 阿狸希望频段宽度越小越好, 但至少要有一个小键. 你的任务就是求出最小的频段宽度.

    注意, 输入不保证全部键都有效时只有一个小阿狸家族。

    和昨天的题有点类似,不过不满足二分性,就枚举一下频段的上下界,用并查集维护代价就好了。

    T2

    题目大意

    给出一个n个点,m条边的有向图,每个点初始的值有正有负。你可以在每一个点加上一个数或是减去一个数,代价为你所选择的数*你所选择的点的加或减的费用(加减费用可以不同)。你也可以通过一条边把一定大小的数从起点“运”到终点,设为所运输数为x,则代价为a∗x2+b∗xa∗x2+b∗x。a,b为这条边的基础属性。且每条边有运输上界r和下界l,求把所有点的数都变为0的最小代价。

    拿了5分的没有边的情况

    其实考场上就想到是上下界费用流,图都建好了,然而不会打…

    正解

    很明显的网络流模型。从原点向每个点连上界为∞,下界为0,费用为它加一个数的代价的边。表示你可以任意的加上一个数。从每个点向汇点连上界为∞,下界为0,费用为它减一个数的代价的边。表示你可以任意的减少一个数。然后对于每一个正权点,从原点向它连上界和下界都为它的权值,费用为0的边,表示你这个点之前就有这么大的数。对于每一个负权点,从它向汇点连上界和下界都为它的权值的相反数,费用为0的边,表示你还需要这么大的数。对于每一条边,由于它是二次的,于是我们可以把它拆成一堆边,每条边的上界为1,下界为0。即a+b,3∗a+b,5∗a+b...a+b,3∗a+b,5∗a+b...这样就能表示所有情况了。最后再跑一遍上下界最小费用可行流就行了。注意,由于这样拆边会导致边数过大,于是我们可以使用动态加边大法。

    作者:alan_cty

    怎么又是网络流啊

    T3

    题目大意

    刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.

    刚才说过, 阿狸的国家有n 个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通.

    为了省钱, 每两个城市之间最多只能有一条直接的贸易路径. 对于两个建立路线的方案, 如果存在一个城市对, 在两个方案中是否建立路线不一样, 那么这两个方案就是不同的, 否则就是相同的. 现在你需要求出一共有多少不同的方案.

    好了, 这就是困扰阿狸的问题. 换句话说, 你需要求出n 个点的简单(无重边无自环)无向连通图数目.

    由于这个数字可能非常大, 你只需要输出方案数mod 1004535809(479 * 2 ^21 + 1)即可.

    不会做…10分暴力都不会打…

    忘记可以打表水分了

    正解

    正难则反。

    设g[n]表示有n个点的无向图的数量(不一定联通),g[n]显然等于(2^{C_m^2}),(m=frac{n(n-1)}{2})

    我们可以采取一种递推的方式来计算 n 个点的联通无向图有多少种, 记为 f[n].

    考虑节点 1 所在的连通块, 枚举它的大小, 我们能够得到 n 个点的所有不连通的无向图个数,
    (sum_{i=1}^{n-1}{C(n, i)g[n-i]f[i]})

    那么(f[n]=g[n] - sum_{i=1}^{n-1}{C(n, i)f[i]g[n-i]})

    把组合数拆开变成卷积的形式,套分治NTT即可(然而我并不会NTT

    小结

    1. 再简单的题也要对拍,要出数据验证!!
    2. 我的知识面还是太窄了呀

    花絮

    xzb第三题(n^2)卡过了十三万的数据!

    赛后,发现没什么题可以改,于是重操旧业,又开启一段n方过十万的艰辛历程。。。

    第1步:看着我的方程
    s=(s+f[k]*g[i-k]%mo*fac[i-1]%mo*inv[k-1]%mo*inv[i-k])%mo;
    (fac是阶乘,inv是阶乘的逆元)
    发现fac[i-1]可以提出来,从而少一个mo

    第2步:式子变成
    s=(s+f[k]*g[i-k]%mo*inv[k-1]%mo*inv[i-k])%mo;
    后,我又发现f[k]和inv[k-1]可以预先记录下来乘在一起,g[i-k]和inv[i-k]也是
    A[i]=f[i]*inv[i-1]%mo;B[i]=g[i]*inv[i]%mo;
    于是mo只剩下了一个,稳稳的65分

    第3步:争取把mo去掉
    我发现一个比较大的数字可以表示为:v2^x+u,
    然后n
    mo2是1023左右,x取40足够

    第4步:指针代替数组(老套路*1),我的式子变成了
    v+=(u+=1ll**(++p)**(--q))>>40,u&=1099511627775;
    我的代码是不是越来越丑了?我也觉得。
    没事,后面还有更丑的

    第5步,循环展开(老套路*2)
    无论是for循环还是while循环,每次操作的时候常数都比较大
    于是,我让指针在每次for循环中移动4次,从而使for循环常数大大减小
    注:移动几次视情况而定,有时8次快,有时4次快
    把上面代码重复4次即可
    现在有90分了

    第6步,终结的一步
    我们之所以要让u&=1099511627775
    就是因为我怕u爆long long,然而计算器证明,(263-1)/(mo2)>9
    这意味着什么?
    这说明,每算9次,只用做一次
    v+=u>>40,u&=1099511627775

    所以,我们定一个参数p(小于等于9),每p个运算中,有p-1个可以直接写成
    u+=1ll(++p)(--q)
    这个优化就很有效了,倒数第三个点直接从3861ms变成2140ms

    就此AC

    By 2016徐子博

    #include<bits/stdc++.h> #define O3 __attribute__((optimize(3))) #define rep(i,a,b) for(int i=a;i<=(b);i++) using namespace std; typedef long long ll; typedef unsigned long long ull; #define mo 1004535809 const int N=1.3e5+4; O3 ll Pow(ll x,ll y){ ll s=1; for(;y;y>>=1,x=x*x%mo)if(y&1)s=s*x%mo; return s; } int n; ll fac[N],inv[N]; ll f[N],g[N]; int A[N],B[N]; O3 int main(){ scanf("%d",&n); fac[0]=1; rep(i,1,n)fac[i]=fac[i-1]*i%mo; inv[n]=Pow(fac[n],mo-2); for(int i=n-1;i;i--)inv[i]=inv[i+1]*(i+1)%mo; inv[0]=1; rep(i,1,n){ g[i]=Pow(2,1ll*i*(i-1)/2); register int*p=A,*q=B+i; register ll u(0),v(0),s; for(int k(0);k+8<=i;k+=8){ v+=(u+=1ll**(++p)**(--q))>>40,u&=1099511627775; u+=1ll**(++p)**(--q); u+=1ll**(++p)**(--q); u+=1ll**(++p)**(--q); u+=1ll**(++p)**(--q); u+=1ll**(++p)**(--q); u+=1ll**(++p)**(--q); u+=1ll**(++p)**(--q); } rep(l,1,i&7) v+=(u+=1ll**(++p)**(--q))>>40,u&=1099511627775; s=(v%mo*((1ll<<40)%mo)+u)%mo; f[i]=(g[i]-s*fac[i-1])%mo; if(f[i]<0)f[i]+=mo; A[i]=1ll*f[i]*inv[i-1]%mo; B[i]=1ll*g[i]*inv[i]%mo; } printf("%d",f[n]); }
    

    xzb暴力100分了!%%%
    这,是真正的N方过十万,不,不止十万,是十三万。这也没有什么剪枝,扎扎实实地跑满了N方的复杂度

    这也不是什么加法之类的常数极小,容易卡的运算

    这是实打实的,longlong级乘法加1e9的取模!

    题目的5s时限,是为了NTT等多项式算法开的

    却败在了这伟大的卡常之下!

    有诗为证:卡常大师徐子博!普天同庆膜膜膜!

    卡常界的集大成者,循环展开的宗师,底层优化的至强者,attribute((optimize("O3")))的的归宗者,我们高呼着,徐子博!徐子博!

    By 2016姚敏清

    xzbtql%%%

  • 相关阅读:
    MDX查询语句
    MyEclipse 点击 部署 按钮 无效
    C#创建数字证书并导出为pfx,并使用pfx进行非对称加解密
    SSIS – 变量和表达式
    使用 SSIS Foreach Loop 容器 – Foreach Item Enumerator
    SSIS – For Loop Container
    SSIS 中的文件系统任务 (File System Task)
    TypeError: parse() got an unexpected keyword argument 'transport_encoding' 安装tensor后报错
    np基本函数大全
    使用OpenCV对图像进行缩放
  • 原文地址:https://www.cnblogs.com/leason-lyx/p/11147327.html
Copyright © 2011-2022 走看看