前言

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逆向】反调试绕过(nop 绕过)

    1. 这是看雪上的一个题目,要求显示出 it is success https://www.kanxue.com/work-task_read-800648.htm 第三题 2. apk 安装到手机, ...

  2. [Android 逆向]Xposed 破解 切水果大战原版.apk

    代码 public class Main implements IXposedHookLoadPackage { boolean flag = false; @Override public void ...

  3. Qt实用技巧:Qt从QtCreator更换为VS开发Qt所需要注意的坑

    前言   基本都是使用QtCreator开发,使用vs进行一下开发,记录从QtCreator换成VS所遇到的注意的坑.   VS装对应的Qt版本助手配置Qt版本        VS装番茄助手   这里 ...

  4. zip压缩模块,tarfile压缩模块,包和模块,format格式化的复习--day17

    1.zipfile模块 import zipfile #导入模块 1.压缩文件 (1)创建压缩包 参数1压缩包名字,参数2以w模式创建,参数3压缩固定写法 zf = zipfile.ZipFile(& ...

  5. 无法加载 DLL“librdkafka”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)

    我这个错误是在引用了封装kafka项目的情况下提示的. 解决方案:在本项目里面安装 RdKafka ,再次运行就好了.

  6. Redis加Lua脚本实现分布式锁

    先讲一下为什么使用分布式锁: 在传统的单体应用中,我们可以使用Java并发处理相关的API(如ReentrantLock或synchronized)来实现对共享资源的互斥控制,确保在高并发情况下同一时 ...

  7. 【LeetCode回溯算法#04】组合总和I与组合总和II(单层处理位置去重)

    组合总和 力扣题目链接(opens new window) 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target ...

  8. 【Azure API 管理】 为APIM创建一个审批订阅申请的RBAC角色,最少的Action内容是什么呢?

    问题描述 在使用APIM服务中,需要为专门的一组用户赋予特殊的权限:审批APIM用户的对产品的订阅.需要自定义一个RBAC角色,那么如何来设置最少的Action满足需求呢? 问题解答 要对APIM订阅 ...

  9. 【Azure 环境】台湾同胞:詢問大陸所有廠牌手機是否都可透過通知中心發送訊息

    什么是 Azure 通知中心? Azure 通知中心提供易于使用且向外扩展的推送引擎,可用于将通知发送到任何平台 (iOS.Android.Windows.Kindle.百度等 ) 从任何后端 (云和 ...

  10. 使用 MyBatis 操作 Nebula Graph 的实践

    本文首发于 Nebula Graph Community 公众号 我最近注意到很多同学对于 ORM 框架的需求比较迫切,而且有热心的同学已经捐赠了自己开发的项目,Nebula 社区也在 working ...