前言

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. Java缓存框架整理

    Spring Cache 为基于Spring框架的应用提供了一套完整的缓存API抽象,具体的缓存实现可以对接如Ehcache,Redis等. https://docs.spring.io/spring ...

  2. Vulnhub内网渗透DC-7靶场通关

    个人博客: xzajyjs.cn DC系列共9个靶场,本次来试玩一下一个 DC-7,下载地址. 下载下来后是 .ova 格式,建议使用vitualbox进行搭建,vmware可能存在兼容性问题.靶场推 ...

  3. Java纯手打web服务器(一)

    目录 在主线程中进行等待客户端请求: 这里主要说下解析流程: 在主线程中进行等待客户端请求: public static void main(String[] args) { HttpServer1 ...

  4. 【Azure Developer】示例: 在中国区调用MSGraph SDK通过User principal name获取到User信息,如Object ID

    问题描述 示例调用MSGraph SDK通过User principal name获取到User信息,如Object ID. 参考资料 选择 Microsoft Graph 身份验证提供程序 : ht ...

  5. 【Azure 存储服务】Azure Storage Account 下的 Table 查询的性能调优

    问题描述 Azure Storage Account 下的 Table 查询的性能调优? 问题解答 因为Azure Storage Table服务(表服务) 与常规的关系型数据库不一样(例如:MySQ ...

  6. Dockerfile编写(备份)

    1-使用#注释 2-Dockerfile 主体内容分为四部分:基础镜像信息. 维护者信息. 镜像操作指令和容器启动时执行指令 简单示例: FROM   xxx:latest   #基于xxx:late ...

  7. linux复习基础命令

    Linux基础命令 学习目标 了解vm备份的两种方式 了解快照和克隆的区别 了解linux系统文件 掌握基础命令 指定vmtools的作用 1 vm两种备份方式 为什么要进行备份 保证centos操作 ...

  8. Java abstract 小测试

    1 package com.bytezreo.abstractTest; 2 3 /** 4 * 5 * @Description abstract 小测试 6 * @author Bytezero· ...

  9. 2022 Gartner RPA魔力象限,弘玑Cyclone位置飞跃国产RPA进击全球

    文/王吉伟 7月25日,国际权威分析机构Gartner发布了2022全球RPA魔力象限报告(Gartner RPA MQ),UiPath.Automation Anywhere.微软等来自全球的15家 ...

  10. MYSQL中正则表达式检索数据库

    1.MySQL中使用通配符检索数据库,之外还可以使用正则表达式来检索数据. 使用通配符   '_'  和   '%'的区别如下,   使用通配符的技巧:一般的来说 通配符可以处理数据,但是消耗内存较大 ...