点此进入比赛

得分: \(100+100+20=220\)(\(T1\)打了两个小时,以至于\(T3\)没时间打了,无奈交暴力)

排名: \(Rank\ 8\)

\(Rating\):\(+19\)

\(T1\):【HHHOJ126】求和(点此看题面)

看到这道题,我不由得想到这道题目:【BZOJ1257】[CQOI2007] 余数之和。

于是就想到用除法分块去做。

但是,由于记错了平方和公式(我毕竟还是太弱了... ...),结果打了两个小时... ...

如果我们暂时把\(i≠j\)这个诡异的限制抛开不顾,则不难发现,\((n\%i)\)这一项与\(j\)无关,\((m\%j)\)这一项与\(i\)无关,所以我们可以把原式分成两部分:

\[\sum_{i=1}^n(n\%i)*\sum_{j=1}^m(m\%j)
\]

如果用\(f(x)\)表示\(\sum_{i=1}^x(x\%i)\),则原式就可以表示为:

\[f(n)·f(m)
\]

关于\(f(n)\)怎么求,我想在【BZOJ1257】[CQOI2007] 余数之和这题的题解中我应该讲得很清楚了吧。

但是,此时求得的答案包括了\(i=j\)的情况。

所以我们要将\(i=j\)的答案从答案中减去。

首先,不难发现,在\(i=j\)时的答案是长这样的(代入原式计算即可):

\[\sum_{i=1}^{min(n,m)}(n\%i)(m\%i)
\]

依据对取模运算转化的常见套路,我们可以将其转化成这个样子:

\[\sum_{i=1}^{min(n,m)}(n-\lfloor\frac ni\rfloor*i)(m-\lfloor\frac mi\rfloor*i)
\]

拆括号得:

\[\sum_{i=1}^{min(n,m)}(nm-mi\lfloor\frac ni\rfloor-ni\lfloor\frac mi\rfloor+i^2\lfloor\frac ni\rfloor\lfloor\frac mi\rfloor)
\]

这个式子显然是可以用除法分块来做的。

于是就解决了呀。

#include<bits/stdc++.h>
#define LL long long
#define ten(x) (((x)<<3)+((x)<<1))
#define MOD 19940417
#define min(x,y) ((x)<(y)?(x):(y))
#define Inc(x,y) ((x+=(y))>=MOD&&(x-=MOD))
#define Dec(x,y) ((x-=(y))<0&&(x+=MOD))
#define f(x) ((((x)*((x)+1)>>1)%MOD)*((((x)<<1)+1)%MOD)%MOD*6646806%MOD)
#define g(x,y) ((((x)+(y))*((y)-(x)+1)>>1)%MOD)
using namespace std;
LL n,m;
class FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
#define pc(ch) (putchar(ch))
LL Top;char ch,*A,*B,Fin[Fsize],Stack[Fsize];
public:
FIO() {A=B=Fin;}
inline void read(LL &x) {x=0;while(!isdigit(ch=tc()));while(x=ten(x)+(ch&15),isdigit(ch=tc()));}
inline void write(LL x) {if(!x) return (void)(pc('0'));while(x) Stack[++Top]=x%10+48,x/=10;while(Top) pc(Stack[Top--]);}
}F;
inline LL Operate(LL x)//除法分块,类似于余数求和
{
register LL l,r,res=x*x%MOD;
for(l=1;l<=x;l=r+1) r=x/(x/l),Dec(res,g(l,r)*(x/l)%MOD);
return res;
}
int main()
{
register LL l,r,lim,ans;
F.read(n),F.read(m),ans=Operate(n)*Operate(m)%MOD;
for(l=1,Dec(ans,(lim=min(n,m))*n%MOD*m%MOD);l<=lim;l=r+1)//根据上面求出的式子,再一次除法分块,减去多余的答案
{
r=min(n/(n/l),m/(m/l)),
Dec(ans,(f(r)-f(l-1))%MOD*(n/l)%MOD*(m/l)%MOD),
Inc(ans,g(l,r)*n%MOD*(m/l)%MOD),
Inc(ans,g(l,r)*m%MOD*(n/l)%MOD);
}
return F.write(ans),0;
}

\(T2\):【HHHOJ127】排队(点此看题面)

这题没想到竟能在考试时间内做出来。

快速幂写炸调了半个多小时祭。(深深感受到了自己的菜)

首先,这种题目一看到,肯定先敲一个组合数板子。

然后就是乱搞(\(DFS\)遍历\(+\)玄学转移),结果莫名其妙过了样例!

更神奇的是,一交居然\(A\)了!

其实这题也不是很难,就是组合数的一个应用,感觉还是挺好推的,这里就省略了。

具体实现可以见代码:

#include<bits/stdc++.h>
#define ten(x) (((x)<<3)+((x)<<1))
#define N 1000
#define MOD 10007
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
using namespace std;
int n,ee=0,lnk[N+5];
struct edge
{
int to,nxt;
}e[N+5];
class FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
#define pc(ch) (putchar(ch))
int Top;char ch,*A,*B,Fin[Fsize],Stack[Fsize];
public:
FIO() {A=B=Fin;}
inline void read(int &x) {x=0;while(!isdigit(ch=tc()));while(x=ten(x)+(ch&15),isdigit(ch=tc()));}
inline void write(int x) {if(!x) return (void)(pc('0'));while(x) Stack[++Top]=x%10+48,x/=10;while(Top) pc(Stack[Top--]);}
inline void write_char(char x) {pc(x);}
}F;
class Class_Math//组合数
{
private:
int Fac[N+5],Inv[N+5];
inline int quick_pow(int x,int y,register int res=1)//快速幂写炸调了半个多小时
{
for(;y;x=1LL*x*x%MOD,y>>=1) if(y&1) res=1LL*res*x%MOD;
return res;
}
public:
Class_Math()//预处理出阶乘和阶乘逆元
{
register int i;
for(Fac[0]=1,i=1;i<=N;++i) Fac[i]=Fac[i-1]*i%MOD;
for(Inv[N]=quick_pow(Fac[N],MOD-2),i=N-1;i>=0;--i) Inv[i]=Inv[i+1]*(i+1)%MOD;
}
inline int C(int x,int y) {return 1LL*Fac[x]*Inv[y]%MOD*Inv[x-y]%MOD;}//求组合数
}Math;
class Class_DfsSolver//DFS遍历
{
private:
int ans[N+5],Size[N+5];//ans记录当前子树内的方案数,Size记录子树大小
inline void dfs(int x)
{
register int i;
for(ans[x]=1,Size[x]=0,i=lnk[x];i;i=e[i].nxt)//玄学转移
dfs(e[i].to),Size[x]+=Size[e[i].to],ans[x]=1LL*ans[x]*ans[e[i].to]%MOD*Math.C(Size[x]-1,Size[e[i].to]-1)%MOD;
++Size[x];
}
public:
inline void Solve() {dfs(1),F.write(ans[1]),F.write_char('\n');}
}DfsSolver;
int main()
{
register int i,x,y,T;F.read(T);
while(T--)
{
for(F.read(n),i=1,ee=0;i<=n;++i) lnk[i]=0;
for(i=1;i<=n;++i) for(F.read(x);x;--x) F.read(y),add(i,y);
DfsSolver.Solve();
}
return 0;
}

\(T3\):【HHHOJ128】城市(点此看题面)

原题: 【51nod1743】雪之国度

由于\(T1\)打了两个多小时,结果虽然这题\(Manchery\)讲评过,但是没时间打了,直接交了暴力。

其实这题实现起来真的要比想象中简单一些,题解可以参考上面的链接。

代码如下:

#include<bits/stdc++.h>
#define ten(x) (((x)<<3)+((x)<<1))
#define N 100000
#define M 500000
#define LogN 20
#define INF 1000000000
#define add(x,y,z) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y,e[ee].val=z)
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)<0?-(x):(x))
using namespace std;
int n,m,ee=0,val[N+5],lnk[N+5];
struct edge
{
int from,to,nxt,val,vis;
inline friend bool operator < (edge x,edge y) {return x.val<y.val;}
}s[M+5],e[(N<<1)+5];
class FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,Fsize,stdout),Fout[(FoutSize=0)++]=ch))
int Top,FoutSize;char ch,*A,*B,Fin[Fsize],Fout[Fsize],Stack[Fsize];
public:
inline void read(int &x) {x=0;while(!isdigit(ch=tc()));while(x=ten(x)+(ch&15),isdigit(ch=tc()));}
inline void write(int x) {if(!x) return (void)(pc('0'));while(x) Stack[++Top]=x%10+48,x/=10;while(Top) pc(Stack[Top--]);}
inline void write_char(char x) {pc(x);}
inline void write_string(string x) {for(register int i=0,len=x.length();i<len;++i) pc(x[i]);}
inline void clear() {fwrite(Fout,1,FoutSize,stdout);}
}F;
class UnionFindSet
{
public:
int fa[N+5];
inline void Clear() {for(register int i=1;i<=N;++i) fa[i]=i;}
UnionFindSet() {Clear();}
inline int getfa(int x) {return fa[x]^x?fa[x]=getfa(fa[x]):x;}
inline void Union(int x,int y) {if((x=getfa(x))^(y=getfa(y))) fa[y]=x;}
}U;
class Class_MulSolver
{
public:
int Depth[N+5],fa[N+5][LogN+5],Max[N+5][LogN+5];
private:
inline void dfs(int x,int lst)
{
for(register int i=lnk[x];i;i=e[i].nxt)
if(e[i].to^lst) Depth[e[i].to]=Depth[fa[e[i].to][0]=x]+1,Max[e[i].to][0]=e[i].val,dfs(e[i].to,x);
}
public:
inline void DfsInit() {dfs(1,0);}
inline void MulInit() {for(register int i,j=1;j<=LogN;++j) for(i=1;i<=n;++i) fa[i][j]=fa[fa[i][j-1]][j-1],Max[i][j]=max(Max[i][j-1],Max[fa[i][j-1]][j-1]);}
inline int get_max(int x,int y)
{
if(Depth[x]<Depth[y]) swap(x,y);
register int i,res=0;
for(i=0;Depth[x]^Depth[y];++i) if((Depth[x]^Depth[y])&(1<<i)) res=max(res,Max[x][i]),x=fa[x][i];
if(!(x^y)) return res;
for(i=0;fa[x][i]^fa[y][i];++i);
for(--i;i>=0;--i) if(fa[x][i]^fa[y][i]) res=max(res,max(Max[x][i],Max[y][i])),x=fa[x][i],y=fa[y][i];
return max(res,max(Max[x][0],Max[y][0]));
}
}MulSolver;
int main()
{
register int i,Q,x,y;
for(F.read(n),F.read(m),F.read(Q),i=1;i<=n;++i) F.read(val[i]);
for(i=1;i<=m;++i) F.read(s[i].from),F.read(s[i].to),s[i].val=abs(val[s[i].from]-val[s[i].to]);
for(sort(s+1,s+m+1),i=1;i<=m;++i) if(U.getfa(s[i].from)^U.getfa(s[i].to)) U.Union(s[i].from,s[i].to),s[i].vis=1,add(s[i].from,s[i].to,s[i].val),add(s[i].to,s[i].from,s[i].val);
for(U.Clear(),MulSolver.DfsInit(),i=1;i<=m;++i)
{
if(s[i].vis) continue;
for(x=U.getfa(s[i].from),y=U.getfa(s[i].to);x^y;x=U.getfa(x))
{
if(MulSolver.Depth[x]<MulSolver.Depth[y]) swap(x,y);
MulSolver.Max[x][0]=s[i].val,U.fa[x]=MulSolver.fa[x][0];
}
}
for(MulSolver.MulInit();Q;--Q) F.read(x),F.read(y),(U.getfa(x)^U.getfa(y)?F.write_string("infinitely\n"):(F.write(MulSolver.get_max(x,y)),F.write_char('\n')));
return F.clear(),0;
}

【HHHOJ】NOIP2018 模拟赛(二十五) 解题报告的更多相关文章

  1. EZ 2018 05 20 NOIP2018 模拟赛(十五)

    这次的比赛充满着玄学的气息,玄学链接 首先讲一下为什么没有第十四场 其实今天早上9点时看到题目就叫了:原题! 没错,整套试卷都做过,我还写了题解 然后老叶就说换一套,但如果仅仅是这样就没什么 但等13 ...

  2. NOIp2018模拟赛四十五~??

    欠的太多,咕了咕了 最近复赛临近时间紧,就不每次都写感想和题解了,只写点有意义的好题

  3. NOIp2018模拟赛三十五

    两道大数据结构把我砸懵 成绩:未提交 Orz xfz两道正解 A:[BZOJ4049][CREC2014B]mountainous landscape B:CJB的大作(CF改编题)

  4. [NOIP2018模拟赛10.16]手残报告

    [NOIP2018模拟赛10.16]手残报告 闲扯 炉石乱斗模式美滋滋啊,又颓到好晚... 上来T2先敲了树剖,看T1发现是个思博DP,然后没过大样例,写个暴力发现还是没过大样例!?才发现理解错题意了 ...

  5. NOIp2018模拟赛四十二

    今天看标题终于回到了“NOIP模拟赛”,十分高兴啊! 然后一打开题目: ********** 所以今天又是一场NOIPlus模拟赛(微笑) 成绩:0+70+0=70 A题想了个贪心被myh两分钟cha ...

  6. NOIp模拟赛二十八

    (这是NOIp模拟赛?应该是NOI模拟赛不小心加了个p) 嗯,假装这是正经的NOIp模拟赛,从今天开始也写写题解吧(这几天被虐的惨惨) 今日情况:8+50+0=58 A题输出样例,B题正解写挂,C题不 ...

  7. EZ 2018 06 17 NOIP2018 模拟赛(十九)

    这次的题目难得的水,但是由于许多哲学的原因,第二题题意表述很迷. 然后是真的猜题意了搞了. 不过这样都可以涨Rating我也是服了. Upt:链接莫名又消失了 A. 「NOIP2017模拟赛11.03 ...

  8. EZ 2018 06 10 NOIP2018 模拟赛(十八)

    好久没写blog&&比赛题解了,最近补一下 这次还是很狗的,T3想了很久最后竟然连并查集都忘写了,然后T2map莫名爆炸. Rating爆减......链接不解释 好了我们开始看题. ...

  9. NOIp2018模拟赛三十六

    好久没打模拟赛了...今天一样是两道国集,一道bzoj题 成绩:13+0+95=108 A题开始看错题了...导致样例都没看懂,结果xfz提醒我后我理解了一个我自认为正确的题意(事实证明我和xfz都错 ...

  10. NOIp模拟赛二十九

    又是受虐的一天呢~接下来四天都要打模拟赛QAQ 今日分数:0(100)+100+0=100 A题O(读入)结论题判断结果时没return 0被subtask卡成0分,喜提fstQAQ,B题DP,C题不 ...

随机推荐

  1. Unity3D -- shader光照常用函数和变量

    上一篇记录了shader常用函数和变量,这篇记录一些光照计算时常用函数和变量 1.内置的光照变量 _LightColor0 float4 //该Pass处理的逐像素光源的颜色 _WorldSpaceL ...

  2. cf837E(xjb)

    题目链接:http://codeforces.com/problemset/problem/837/E 题意:f(a, 0) = 0 ,     f(a, b) = 1 + f(a, b - gcd( ...

  3. linux_下IP、网关、DNS地址配置

    设置Linux网络的方法有两种: 第一种:修改配置文档(需要重启网络配置,永远生效)一.修改IP地址[aeolus@db1 network-scripts]$ vi ifcfg-eth0DEVICE= ...

  4. css 权重值(层叠性)详解

    目录 css权重值(重叠性)实例 权重值的计算 !important 提升权重值实例 什么情况下可以使用!important ? 总结: css权重值(重叠性)实例 css中有很多选择器,那在多个选择 ...

  5. 消息中间件 | 消息协议 | AMQP -- 《分布式 消息中间件实践》笔记

    04年,AMQP开放标准被开发 06年,AMQP规范被发布   基本概念     Message:与平台无相关的数据.     Publisher:向交换器发布消息的客户端应用程序     Excha ...

  6. POJ1032 Parliament

    题目来源:http://poj.org/problem?id=1032 题目大意:给定一个正整数N(5<=N<=1000),将N拆为若干个不同的数使得它们的乘积最大(找到一组互不相等,和为 ...

  7. POJ1845 Sumdiv 数学?逆元?

    当初写过一篇分治的 题意:求A^B的所有因子之和,并对其取模 9901再输出 对于数A=p1^c1+p2^c2+...+pn*cn,它的所有约数之和为(1+p1+p1^2+p1^3+...+p1^(c ...

  8. Linux如何用查看域名解析

    方法/步骤     查看本地dns配置.确保能上网,dns配置正确.可以查看网卡配置文件和dns配置文件,网卡里配置优先.   ping命令.第一行会返回域名及解析的ip.   host命令.会返回域 ...

  9. python3+Appium自动化03-Appium元素检测

    需要导入方法NoSuchElementException from appium import webdriver from selenium.common.exceptions import NoS ...

  10. JAVA多线程之线程池的使用

    合理利用线程池能够带来三个好处. 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. 第三:提高线程 ...