T1:工业题

基本思路

  这题有一个重要的小转化:

我们将原来的函数看作一个矩阵,\(f(i,j-1)*a\)相当于从\(j-1\)向右走一步并贡献a,\(f(i-1,j)*b\)相当于从\(i-1\)向下走一步并贡献b

  那么问题就转化成了求从第\(0\)行与第\(0\)列的所有点走到点\((m,n)\)的所有方案数的总贡献

  在一个点,对于他之前的点的所有走法,他都有可能向下或右走并带来贡献,所以是统计所有方案数。

  易知从点\((i,j)\)到点\((m,n)\)的走的步数是\(m-i+n-j)\),又由于在每一个点都有向下或向右走的可能,我们可以只关注向下(或向右),看每一步向下(或向右)走发生在哪个点,那么方案数就是\(C_{n+m-i}^{n-i}\)(从第0列出发)及\(C_{n+m-i}^{m-i}\)(从第0行出发)

  你这么打了,然后你WA了。。。。。。

  为什么?

  注意:这里的C考虑的是决策点,但是,第0行(列)的点一定会向下(右)走,是不会有决策的,因而正确的式子是:

\[C_{n+m-i-1}^{n-i}andC_{n+m-i-1}^{m-i}
\]

  上代码:

#include<bits/stdc++.h>
using namespace std;
namespace STD
{
#define ll long long
#define rr register
const int SIZE=3e5+4;
const int mod=998244353;
int n,m;
ll a,b,ans;
ll jc[SIZE<<1],inv[SIZE<<1];
ll fn[SIZE],fm[SIZE];
ll b_,a_;
ll qpow(ll base,ll exp)
{
rr ll ret=1ll;
while(exp)
{
if(exp&1) ret=ret*base%mod;
base=base*base%mod;
exp>>=1ll;
}
return ret;
}
inline ll C(ll x,ll y){return jc[x]*inv[y]%mod*inv[x-y]%mod;}
ll read1()
{
rr ll x_read=0ll,y_read=1ll;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=-1;
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=x_read*10+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
int read2()
{
rr int x_read=0ll,y_read=1ll;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=-1;
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=x_read*10+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
};
using namespace STD;
int main()
{
n=read2(),m=read2(),a=read1(),b=read1();
a%=mod,b%=mod;
a_=qpow(a,m);
b_=qpow(b,n);
//由于后面a^m与b^n会大量用到,所以预处理
for(rr int i=1;i<=n;i++){fn[i]=read1();fn[i]%=mod;}
for(rr int i=1;i<=m;i++){fm[i]=read1();fm[i]%=mod;}
jc[0]=inv[0]=1ll;
for(rr int i=1;i<=n+m;i++){jc[i]=1ll*i*jc[i-1]%mod;inv[i]=qpow(jc[i],mod-2);}
for(rr int i=1;i<=n;i++)
ans=(ans+fn[i]*C(n+m-i-1,m-1)%mod*qpow(b,n-i)%mod*a_%mod)%mod;
for(rr int i=1;i<=m;i++)
ans=(ans+fm[i]*C(n+m-i-1,n-1)%mod*b_%mod*qpow(a,m-i)%mod)%mod;
int x=printf("%lld",ans);
}

T2:

基本思路:

  考场上想的普通DP,不对。

  实际上是树形DP

  实际上可以将Y方点看作边,然后将X方点看作点,\(n\)个点\(n\)条边,很明显,去掉一条边后就是树,我们的任务就是求能将所有的边都覆盖的最小代价,一条边被覆盖是指它的两个端点至少有一个被选。

  我们可以判出环来然后删去环里的任一条边,然后以删掉的边的端点跑DP即可

  很明显树形DP,DP式就不写在这了,自己推吧,推不出来就自己上代码里找吧。

  状态数组\(c[i][j](j=0,1)\)表示i被选(j=1)或不被选(j=0)是以他为根的子树的最小代价。

  注意被删掉的边也要被覆盖,所以要在两个端点被选的情况里取min

  代码:

#include<bits/stdc++.h>
using namespace std;
namespace STD
{
#define ll long long
#define rr register
#define pp pair<int,int>
#define fi first
#define se second
#define min(x,y) (x<y?x:y)
#define inf LONG_LONG_MAX
#define IT set<int>::iterator
const int SIZE=1e6+4;
int n,root;
ll ans=inf,a,b;
set<int> to[SIZE];
ll val[SIZE];
ll c[SIZE][2];
bool vis[SIZE];
pp edge;
void dfs(int x,int f)
{
static bool ret=0;
vis[x]=1;
for(IT it=to[x].begin();it!=to[x].end();it++)
{
if(*it==f) continue;
if(vis[*it]){edge.fi=x,edge.se=*it;ret=1;return;}
dfs(*it,x);
if(ret) return;
}
}
void DP(int now,int f)
{
//儿子与父亲必须至少有一个选
for(IT it=to[now].begin();it!=to[now].end();it++)
{
if(*it==f) continue;
DP(*it,now);
c[now][1]+=min(c[*it][0],c[*it][1]);
c[now][0]+=c[*it][1];
//鄙视你的智商,连我都推出来的式子你还推不出来过来看。。。。
}
c[now][1]+=val[now];
}
int read()
{
rr int x_read=0,y_read=1;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=-1;
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read*10)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
};
using namespace STD;
int main()
{
n=read(),a=read(),b=read();
for(rr int i=1;i<=n;i++)
{
int x1=read(),x2=read();
to[x1].insert(x2),to[x2].insert(x1);
val[x1]+=a,val[x2]+=b;
}
dfs(1,1);
to[edge.fi].erase(edge.se);
to[edge.se].erase(edge.fi);
root=edge.fi;
DP(root,root);
ans=min(c[root][1],ans);
for(rr int i=1;i<=n;i++) c[i][0]=c[i][1]=0;
root=edge.se;
DP(root,root);
ans=min(ans,c[root][1]);
printf("%lld",ans);
}

T3:玄学题

基本思路

  当我看到-1的时候就已经想到要判指数的奇偶了,但是不会高效地判。

  其实想来也很简单(事后诸葛亮),\(d\)为偶数的情况不决定奇偶,只有奇数的情况才决定,而约数数为奇数只有完全平方数一种情况。

  证明:

对于每个数,他本身以及1都是他的约数,这就有两个约数了。

假如一个数能被某个数整除,这个数及得数都是其约数,那么,除了某个数平方是这个数,那么他的约数一定成对存在。

而假如有个数的平方是这个数,那么它的商还是他自己,那么他这一“对”就只有他自己。

这个平方数约数个数为奇数。

  假如有\(i=p*x^2\)

  要想使\(d(i*j)\)是奇数那么j必须满足\(j=p*y^2\),那么我们只要统计\([1,m]\)内有几个j满足条件即可。

  首先我们可以写一个线性筛法求出每个i的p,并记录。

  线性筛法:

    p[1]=1;
for(rr int i=2;i<=en;i++)
p[i*i]=1;
for(rr int i=2;i<=n;i++)
if(!p[i])
{
p[i]=i;
for(rr int j=2;j<=en;j++)
{
if(j*j*i>n) break;
p[j*j*i]=i;
}
}

  然后,就有j的个数

\[num=
\]
\[\sqrt{\frac{m}{p}}
\]

  证明:

平方在[1,m]范围内的数最多有\(\sqrt{m}\)个那么平方后\(p\)倍还在范围内的就有\(\sqrt{\frac{m}{p}}\)个

  那么我们的算法就是\(O(n)\)的了。

  代码:

#include<bits/stdc++.h>
using namespace std;
namespace STD
{
#define ll long long
#define rr register
const int SIZE=1e7+4;
int n,ans;
ll m;
int p[SIZE];
ll read()
{
rr ll x_read=0,y_read=1;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read='-';
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read*10)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
};
using namespace STD;
int main()
{
n=read(),m=read();
int en=sqrt(n);
p[1]=1;
for(rr int i=2;i<=en;i++)
p[i*i]=1;
for(rr int i=2;i<=n;i++)
if(!p[i])
{
p[i]=i;
for(rr int j=2;j<=en;j++)
{
if(j*j*i>n) break;
p[j*j*i]=i;
}
}
for(rr int i=1;i<=n;i++)
{
ll x=sqrt(m/(ll)p[i]);
if(x&1ll) ans--;
else ans++;
}
printf("%d",ans);
}

NOIP模拟13「工业题·卡常题·玄学题」的更多相关文章

  1. HZOI20190906模拟39 工业,卡常,玄学

    题面:https://www.cnblogs.com/Juve/articles/11484209.html 工业: 推一个式子,AC 没有用组合数....推了2个多小时 我sbsbsbsbsbsbs ...

  2. NOIP 模拟 $13\; \text{工业题}$

    题解 本题不用什么推式子,找规律(而且也找不出来) 可以将整个式子看成一个 \(n×m\) 矩阵 考虑 \(f_{i,j}\),它向右走一步给出 \(f_{i,j}×a\) 的贡献,向下走一步给出 \ ...

  3. NOIP模拟测试「简单的区间·简单的玄学·简单的填数·简单的序列」

    简单的区间 $update$ 终于$AC$了 找到$(sum[r]+sum[l](sum表示以中间点为基准的sum)-mx)\%k==0$的点 注意这里$sum$表示是以$mid$为基准点,(即$su ...

  4. NOIP模拟测试39,思维禁锢专场「工业题·玄学题·卡常题」

    工业题 题解 抱歉,题解没时间写了 代码 #include<bits/stdc++.h> using namespace std; #define ll long long #define ...

  5. Noip模拟13 2021.7.13:再刚题,就剁手&&生日祭

    T1 工业题 这波行列看反就非常尴尬.....口糊出所有正解想到的唯独行列看反全盘炸列(因为和T1斗智斗勇两个半小时...) 这题就是肯定是个O(n+m)的,那就往哪里想,a,b和前面的系数分开求,前 ...

  6. noip模拟44[我想我以后会碰见计数题就溜走的]

    noip模拟44 solutions 这一场抱零的也忒多了,我也只有45pts 据说好像是把几套题里面最难的收拾出来让我们考得 好惨烈啊,这次的考试我只有第一题骗了40pts,其他都抱零了 T1 Em ...

  7. NOIP 模拟 $13\; \text{卡常题}$

    题解 一道环套树的最小点覆盖题目,所谓环套树就是有在 \(n\) 个点 \(n\) 条边的无向联通图中存在一个环 我们可以发现其去掉一条环上的边后就是一棵树 那么对于此题,我们把所有 \(x\) 方点 ...

  8. NOIP模拟测试13「矩阵游戏&#183;跳房子&#183;优美序列」

    矩阵游戏 考试时思路一度和正解一样,考试到最后还是打了80分思路,结果80分打炸了只得了40分暴力分 题解 算出来第一列的总值,每次通过加每两列之间的差值得出下一列的总值 算第一列我们只需要让当前点* ...

  9. NOIP 模拟 $13\; \text{玄学题}$

    题解 题如其名,是挺玄学的. 我们发现每个值是 \(-1\) 还是 \(1\) 只与它的次数是奇是偶有关,而 \(\sum_j^{j\le m}d(i×j)\) 又只与其中有多少个奇数有关 对于 \( ...

随机推荐

  1. JBoss 5.x/6.x 反序列化漏洞(CVE-2017-12149)

    检测

  2. Docker与k8s的恩怨情仇(七)—— “服务发现”大法让你的内外交互原地起飞

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 第一章:Docker与k8s的恩怨情仇(一)-成为PaaS前浪的Cloud Foundry 第二章:Dock ...

  3. .Net Core微服务——Consul(4):主从、集群

    延续上一篇的话题继续,顺便放上一篇的传送门:点这里. 集群的必要性 consul本身就是管理集群的,现在还需要给consul搞个集群,这是为啥?因为consul单点也容易挂啊!万一管理集群的consu ...

  4. 04.委托Delegation

    1. 基本了解 1.1 委托简述 官方文档 委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用,用于将方法作为参数传递给其他方法,可将任何可访问类或结构中与委托类型匹配的任何方法分配给委 ...

  5. postman怎么调中文

    事先准备 1 安装好postman. 下载网址:https://www.postman.com/downloads/ 2 下载好app.zip中文压缩包,下载地址:https://wws.lanzou ...

  6. 如何将fidd上抓的包移到jmete中

    1.fiddler的安装配置就不说了, 网上有很多资源, 不会太难 2.使用fiddler抓包, 相信进来看这篇文章的博友都已经会使用fiddler抓包 3.打开jmeter, 添加>测试计划& ...

  7. VMware 安装 Centos 7 虚拟机配置网络

    在 Windows 机器上如果想使用 Linux 环境,最方便的方式莫过于使用虚拟机,最常用的软件各位肯定也不陌生,大名鼎鼎的 VMware . 不过这玩意有点稍稍不是那么智能,每次安装 Linux ...

  8. 通过Appium日志,分析其运行原理

    1.启动appium: appium的rest http 接口开始监听 4723 端口: 2.运行 python 脚本: appium接收到一个post请求 /wd/hub/session,并携带了 ...

  9. mybatis中Oracle及mysql插入时自动生成主键以及返回主键

    mysql的方式: 方式一: useGeneratedKeys="true" keyProperty="id" 方式二: <selectKey keyPr ...

  10. 为什么有些容器在docker run的时候需要接 -it ,有些不需要?

    这是我们的Dockerfile文件 FROM busybox ENV sg WANG CMD ["/bin/sh", "-c", "echo wang ...