前言

220菜鸡苟且偷生进入前三十


洛谷 6033 Ryoku 的探索

题目

有一个\(n\)个点\(n\)条边的无向连通图,每条边有长度和美观度(美观度各不相同),

若从点\(x\)出发,每次选择美观度最大的一条边走,如果没有未走过的点就瞬移到前一个点,

问从每个点出发经过全部点的长度


分析

如果没有\(n\)条边的限制就是一个基环树,那么只会有一条边而且必然是环上的边不会被算上,

而且这条边一定是与该点所在的树的根节点所连接,

所以思路特别清晰,拓扑排序判环,然后对于环上的点选取美观度小的一条环上边不选,

那么答案就是边长度总和减去这条边的长度,然后再把这个点的信息复制到子树上,

总时间复杂度\(O(n)\)


代码

#include <cstdio>
#include <cctype>
#include <queue>
#define rr register
using namespace std;
const int N=1000011; long long sum; queue<int>q;
struct node{int y,w,f,next;}e[N<<1];
int n,k=1,deg[N],ls[N],ans[N]; bool v[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(long long ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline void dfs(int x,int now){
ans[x]=now;
for (rr int i=ls[x];i;i=e[i].next)
if (v[e[i].y]&&!ans[e[i].y]) dfs(e[i].y,now);
}
signed main(){
n=iut();
for (rr int i=1;i<=n;++i){
rr int x=iut(),y=iut(),w=iut(),f=iut();
e[++k]=(node){y,w,f,ls[x]},ls[x]=k,sum+=w;
e[++k]=(node){x,w,f,ls[y]},ls[y]=k,deg[x]++,deg[y]++;
}
for (rr int i=1;i<=n;++i) if (deg[i]==1) q.push(i);
while (q.size()){
rr int x=q.front(); v[x]=1; q.pop();
for (rr int i=ls[x];i;i=e[i].next)
if (deg[e[i].y]>1){
--deg[e[i].y];
if (deg[e[i].y]==1) q.push(e[i].y);
}
}
for (rr int root=1;root<=n;++root)
if (!v[root]){
rr int p1=0,p2=0,p;
for (rr int i=ls[root];i;i=e[i].next)
if (!v[e[i].y]){if (p1) p2=i; else p1=i;}
p=e[p1].f<e[p2].f?e[p1].w:e[p2].w,dfs(root,p);
}
for (rr int i=1;i<=n;++i) print(sum-ans[i]),putchar(10);
}

洛谷 6034 Ryoku 与最初之人笔记

题目

\[\sum_{i=0}^n\sum_{j=i+1}^n[i\equiv j\pmod {i\,xor\,j}]
\]

分析O(log^2n)

想要\(i\)和\(j\)在取模\(i\,xor\,j\)的情况下相等,不妨设\(i-x(i\,xor\,j)=j-y(i\,xor\,j)(x<y)\)

那么\((y-x)(i\,xor\,j)=j-i\)也就是\(i\,xor\,j|j-i\)

然而思路行不通了?

通过\(xor\)本质就是不退位的减法,所以\(i\,xor\,j\geq j-i\)

那么两个式子综合起来就是\(i\,xor\,j=j-i\)

什么时候两者相等呢,就是没有出现\(j\)某一位为0且\(i\)某一位是1的情况,

那么不就是只要\(i\)是1,\(j\)必须是\(1\),那不就是\(i|j=j\)(我还打表找规律)

那我可以枚举\(j(1\sim n)\),那么所对应的个数就是2的\(j\)的二进制位为1的个数次方减去1(相同不能统计)

那么\(O(n)\)方法就出来了,恭喜TLE(\(n\leq 10^{18}\))

一般这个范围我都会想数位\(dp\)的呀,那可以统计\(1\sim n\)中二进制位为1的个数为\(x\)的有多少个,

然而我只想到记录当前1的个数,然后如果没有顶着上界就可以统计之后的答案,否则继续搜索,还不用记忆化,统计答案要用到组合数

时间复杂度\(O(log^2n)\),还显得绰绰有余


代码(赛时AC)

#include <cstdio>
#define rr register
using namespace std;
typedef long long lll;
const lll mod=1e9+7;
lll n,ans,d[63],dig[63],dp[63],c[63][63],lenn;
inline lll mo(lll x,lll y){return x+y>=mod?x+y-mod:x+y;}
inline void dfs(int len,bool limit,int now){
if (!len) {dp[now]=mo(dp[now],1); return;}
rr int mx=limit?dig[len]:1;
for (rr int i=0;i<=mx;++i)
if (limit&&i==mx) dfs(len-1,limit,now+i);
else{
for (rr int i=0;i<=len-1;++i)
dp[now+i]+=c[len-1][i];
}
}
signed main(){
scanf("%lld",&n),d[0]=c[0][0]=1,ans=!(n%mod)?0:(mod-n%mod);
for (rr int i=1;i<=62;++i) d[i]=mo(d[i-1],d[i-1]),c[i][0]=c[i][i]=1;
for (rr int i=2;i<=62;++i)
for (rr int j=1;j<i;++j) c[i][j]=mo(c[i-1][j],c[i-1][j-1]);
for (;n;n>>=1) dig[++lenn]=n&1; dfs(lenn,1,0);
for (rr int i=1;i<=lenn;++i) ans=mo(ans,1ll*dp[i]*d[i]%mod);
return !printf("%lld",ans);
}

分析O(logn)

比完赛我去看出题人解题报告,怎么这么短

考虑一下组合数本质

\(C(n,0)*2^0+C(n,1)*2^1+C(n,2)*2^2+\cdots+C(n,n)*2^n=C(n,n)*2^0+C(n,n-1)*2^1+C(n,n-2)*2^2+\cdots+C(n,0)*2^n=(1+2)^n=3^n\)

所以可以把后面那一坨用简单的单项式代替,时间复杂度\(O(log_2n)\)


代码(赛后)

#include <cstdio>
#define rr register
using namespace std;
typedef long long lll;
const lll mod=1e9+7;
lll n,ans,p3[63],p2[63],len;
inline lll mo(lll x,lll y){return x+y>=mod?x+y-mod:x+y;}
signed main(){
scanf("%lld",&n),p2[0]=p3[0]=1;
for (rr int i=1;i<=62;++i) p3[i]=mo(mo(p3[i-1],p3[i-1]),p3[i-1]);
for (rr int i=1;i<=62;++i) p2[i]=mo(p2[i-1],p2[i-1]);
for (rr int i=62;~i;--i) if ((n>>i)&1){//如果这一位是1统计0的答案
ans=mo(ans,1ll*p2[len]*p3[i]%mod),++len;
}
ans=mo(ans,mo(mod-n%mod,p2[len]-1));//首先在前面分析说了要1到n都减去1,所以要减n,而且最后加上2的len次方-1是因为算上$n$自己
return !printf("%lld",ans);
}

洛谷 6035 Ryoku 的逆序对

题目

给定一个数组\(B\),\(B_i=\sum_{i<j}[A_i>A_j]\),\(A\)数组是一个\(1\sim n\)的排列,然而有些B被清空了,问A的可能方案数和\(A\)字典序最小的方案


分析

首先\(B\)和\(A\)一一对应,但如果\(B_i>n-i\)那肯定是不可能的,然后方案数就是\(\prod_{i=1}^n[B_i==-1]*(n-i+1)\)(早知道打表找规律了)

让\(B_i=-1\)的位置变成0就能让字典序最小,然后树状数组+二分解决


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int mod=1000000007,N=1000011;
int n,a[N],c[N],ans=1;
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans*f;
}
inline void print(int ans){if (ans>9) print(ans/10); putchar(ans%10+48);}
inline signed query(int x){rr int ans=0; for (;x;x-=-x&x) ans+=c[x]; return ans;}
inline void add(int x){for (;x<=n;x+=-x&x) --c[x];}
signed main(){
n=iut();
for (rr int i=1;i<=n;++i){
a[i]=iut();
if (a[i]>n-i) ans=0;
else if (a[i]==-1) ans=1ll*ans*(n-i+1)%mod,a[i]=0;
}
print(ans); if (!ans) return 0;
for (rr int i=1;i<=n;++i) c[i]=-i&i;
for (rr int i=1;i<=n;++i){
rr int l=1,r=n;
while (l<r){
rr int mid=(l+r+1)>>1;
if (query(mid-1)<=a[i]) l=mid;
else r=mid-1;
}
putchar(i==1?10:32),print(l),add(l);
}
return 0;
}

洛谷 6036 Ryoku 爱学习

题目


分析

一看到概率一般都是期望dp了,但是怎么求这就是一个问题

首先\(a^b\)把它变成常数\(A\)(毒瘤出题人多项式插值)

设\(dp[i]\)表示前\(i\)个知识的答案

不选\(i\)肯定要加上\((1-p[i])*dp[i-1]\)

但是选了\(i\)就很难计算,那得再开一个

\(s[i]\)表示前\(i\)种知识选择\(i\)的答案,

那么\(s[i]=p[i]*(1-p[i-1])*w[i]*A^0+p[i]*p[i-1]*(1-p[i-2])*(w[i]+w[i-1])*A^1+\cdots\)

首先这一坨也是很难表示的,把有关\(w[i]\)的部分提出来就是

\[s[i]=p[i]*(1-p[i-1])*w[i]+p[i]*p[i-1]*(1-p[i-2])*w[i]*A+\cdots
\]

然后没有写的部分正好还缺了\(s[i-1]*A\)

再把刚刚的结合一下可以得到

\[s[i]=p[i]*(s[i-1]*A+w[i]*((1-p[i-1])*A^0+p[i-1]*(1-p[i-2])*A^1+\cdots))
\]

然而后面这一坨同样可以用\(pr[i]\)表示

先把\(s[i]=p[i]*(s[i-1]*A+w[i]*pr[i])\)

那么\(pr[i]=A*p[i-1]*pr[i-1]+1-p[i-1]\)

所以就可以\(O(n)\)解决了


代码(滚动数组+double快读)

#include <cstdio>
#include <cctype>
#include <cmath>
#define rr register
using namespace std;
const int N=100011;
int n,w[N]; double ans,A,DP,dp,Pr,pR,S,s,P,p;
inline double iut(){
rr int ans1=0,ans2=0,len=1; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans1=(ans1<<3)+(ans1<<1)+(c^48),c=getchar();
if (c=='.'){
c=getchar();
while (isdigit(c)) len=len*10,ans2=ans2*10+(c^48),c=getchar();
return ans1+ans2*1.0/len;
}else return ans1;
}
signed main(){
n=(int)iut(),A=iut(),A=pow(A,iut());
for (rr int i=1;i<=n;++i) w[i]=(int)iut();
for (rr int i=1;i<=n;++i){
P=iut(),Pr=A*p*pR+1-p,S=P*(A*s+Pr*w[i]),
DP=(1-P)*dp+P*(dp-s)+S,dp=DP,p=P,pR=Pr,s=S;
}
return !printf("%lf",DP);
}

Ryoku 的新年欢乐赛的更多相关文章

  1. 无聊的活动/缘生意转(2018 Nova OJ新年欢乐赛B题)解题报告

    题目2(下面的太抓 我重新写了个背景 其他都一样) 无聊的活动 JLZ老师不情愿的参加了古风社一年一度的活动,他实在不觉得一群学生跳舞有什么好看,更不明白坐在身后的学生为什么这么兴奋(看小姐姐),于是 ...

  2. contesthunter CH Round #64 - MFOI杯水题欢乐赛day1 solve

    http://www.contesthunter.org/contest/CH Round %2364 - MFOI杯水题欢乐赛 day1/Solve Solve CH Round #64 - MFO ...

  3. 2014.8.3情人节欢乐赛【Benny的农场】

    Benny的农场 (farm.pas/.c/.cpp) 时间限制:1s.空间限制:128MB 题目描述: Benny有一片农田需要灌溉.农田的形状为矩形,并被分为许多小块.每一块中都有一些水管.共有1 ...

  4. i春秋第二届春秋欢乐赛RSA256writeup

    i春秋第二届春秋欢乐赛writeup 下载之后进行解压 发现四个文件 0x01看到题目是RSA的  又看到public.key 所以直接用kali linux的openssl 0x02可以看到e就是E ...

  5. 2014-10-24 NOIP欢乐赛

    10-24NOIP欢乐赛 ——By 潘智力 题目名称 分火腿 无聊的会议 班服 时间限制 1s 1s 1s 内存限制 64MB 128MB 128MB 输入文件 hdogs.in meeting.in ...

  6. Comet OJ 夏季欢乐赛 篮球校赛

    Comet OJ 夏季欢乐赛 篮球校赛 题目传送门 题目描述 JWJU注重培养学生的"唱,跳,rap,篮球"能力.于是每年JWJU都会举办篮球校赛,来给同学们一个切磋篮球技术的平台 ...

  7. Comet OJ 夏季欢乐赛 Gree的心房

    Comet OJ 夏季欢乐赛 Gree的心房 题目传送门 题目描述 据说每一个走进Gree哥哥心房的小姑娘都没有能够再走出来-- 我们将Gree哥哥的心房抽象成一个n \times mn×m的地图,初 ...

  8. Comet OJ 夏季欢乐赛 分配学号

    Comet OJ 夏季欢乐赛 H 分配学号 题目传送门 题目描述 今天,是JWJU给同学们分配学号的一天!为了让大家尽可能的得到自己想要的学号,鸡尾酒让大家先从 [1,10^{18}][1,1018] ...

  9. Comet OJ 2019 夏季欢乐赛题解

    Comet OJ 2019 夏季欢乐赛题解 我是来骗访问量的 A 完全k叉树 \(n\)个点的完全k叉树的直径. 直接做 B 距离产生美 直接做 C 烤面包片 \(n!!!\mod p\) 显然\(n ...

  10. 【题解】Comet OJ 国庆欢乐赛 简要题解

    [题解]Comet OJ 国庆欢乐赛 简要题解 A 直接做 B 直接做,结论: \[ ans=\max([Max\ge \mathrm{sum}] Max,s[n]/2) \] C 考虑这样一个做法: ...

随机推荐

  1. 【Android 逆向】r0zapataNative.apk 破解

    1. apk 安装到手机,需要输入内容,随便输入,提示fail... 2. apk 导入到jadx中查看一下 MainActivity.java String textData = "b2F ...

  2. HttpURLConnection使用分析

    在项目中遇到各种版本的httpClient,所以想了解一下httpClient的实现 首先查看的是JDK1.1中自带的HttpURLConnection,看一下最初的设计是怎么样的 代码分析 使用Ht ...

  3. 分发函数singledispatch

    import functools @functools.singledispatch() def myfunc(arg): print("default myfunc({!r})" ...

  4. java+mysql学生信息管理系统

    实现:mysql+eclipse(idea设置之后也可运行)+jdk8 功能: 管理员:管理登+管理员注册 学生:添加学生信息+删除学生信息+修改学生信息+查询学生信息+学生列表展示 界面展示: 详情 ...

  5. 第137篇:重学ES6模块化

    好家伙,   我原本以为学完模块化之后,就能非常顺利的完成我的项目分包, 然而并没有,这是非常重要的知识,而我没有学好 所以我决定重学一遍   本篇为<阮一峰 ECMAScript 6 (ES6 ...

  6. 【Azure App Service for Linux】Linux Web App如何安装系统未安装的包

    问题描述 Linux Web App中如何安装系统默认未安装的包,如何来执行如 apt install XXX命令呢?现在遇见的问题时,通过Azure App Service门户中的SSH登录后,执行 ...

  7. Program type already present: com.xxx

    该错误是由于工程中存在着相同的类导致(包名与类名都相同),有可能是不同的依赖中有着相同的类,全局搜索该类便可得知

  8. mybatis缓存源码解析

    为什么使用缓存 减少和数据库交互次数,提高执行效率 mybatis的缓存 mybatis一级缓存,也就是局部的sqlSession级别的缓存,默认是开启的 每一个 session 会话都会有各自的缓存 ...

  9. 案例7:将"picK"译成密码

    密码规则:用当前字母后面的第五各字符来代替当前字符.比如字符'a'后面的第5个字符为'f', 则使用'f'代替'a'.编写程序,实现该功能. 示例代码如下: #define _CRT_SECURE_N ...

  10. TimeLine 时间轴 网站 分享 time.graphics - nodejs 10年图

    话说20年 弹指一挥间 https://time.graphics/line/682014 nodejs 10年图 https://time.graphics/line/598790 资料 2022, ...