1.公约数 (gcd.cpp\c\pas)

【问题描述】 给定一个正整数,在[1,n]的范围内,求出有多少个无序数对(a,b)满足 gcd(a,b)=a xor b。

【输入格式】 输入共一行,一个正整数n。

【输出格式】 输出共一行,一个正整数表示答案。

【输入输出样例】 gcd.in  3

gcd.out 1

解释:只有(2,3)满足要求

【数据范围】 对于30%的数据满足n<=1000 对于60%的数据满足n<=10^5 对于100%的数据满足n<=10^7

拿到题就打了30分版本,没推出来公式。

60分版本:

设a^b=c,所以可得a^c=b;

-->gcd(a,a^c)=c;

然后通过枚举a,c完成代码

复杂度O(nlog(n^2))

100分版本:

在60分版本上,加上以下公式:

首先,a=b肯定无解,不妨设a>b:

1:gcd(a,b)是a,b的因数,a-b中也有gcd(a,b)这个因数--->a-b>=gcd(a,b);

2:显然,a^b>=a-b,因为异或不同的地方为1,而减法会牵扯借位;

所以得到gcd(a,b)<=a-b<=a^b;

因为gcd(a,b)=a^b

所以a^b=a-b=gcd(a,b)=c;

b=a-c;

所以只需判断a^c是否等于a-c即可

枚举c,a=i*c

复杂度O(nlog(n))

#include<cstdio>
int main()
{
int n,ans=;
scanf("%d",&n);
for(int i = ; i <= n ; ++i)
for(int j = n/i ; j >= ; --j)
{
int a=j*i;
if((i^a)==(a-i))++ans;
}
printf("%d",ans);
return ;
}

2.通讯 (message.cpp\c\pas)

【问题描述】“这一切都是命运石之门的 选择。” 试图研制时间机器的机关 SERN 截获了中二科学家伦太郎发往过去的一条 短信,并由此得知了伦太郎制作出了电话微波炉(仮)。 为了掌握时间机器的技术,SERN 总部必须尽快将这个消息通过地下秘密通讯 网络,传达到所有分部。 SERN 共有 N 个部门(总部编号为 0),通讯网络有 M 条单向通讯线路,每条 线路有一个固定的通讯花费 Ci。 为了保密,消息的传递只能按照固定的方式进行:从一个已知消息的部门向 另一个与它有线路的部门传递(可能存在多条通信线路)。我们定义总费用为所 有部门传递消息的费用和。 幸运的是,如果两个部门可以直接或间接地相互传递消息(即能按照上述方法 将信息由 X 传递到 Y,同时能由 Y 传递到 X),我们就可以忽略它们之间的花费。 由于资金问题(预算都花在粒子对撞机上了),SERN 总部的工程师希望知道, 达到目标的最小花费是多少。

【输入格式】多组数据,文件以 2 个 0 结尾。 每组数据第一行,一个整数 N,表示有 N 个包括总部的部门(从 0 开始编号)。 然后是一个整数 M,表示有 M 条单向通讯线路。 接下来 M 行,每行三个整数,Xi,Yi,Ci,表示第 i 条线路从 Xi 连向 Yi,花费 为 Ci。

【输出格式】 每组数据一行,一个整数表示达到目标的最小花费。

【数据范围】对于 10%的数据, 保证 M=N-1 对于另 30%的数据,N ≤ 20 ,M ≤ 20 对于 100%的数据,N ≤ 50000 , M ≤ 10^5 ,Ci ≤ 10^5 ,数据组数 ≤ 5 数据保证一定可以将信息传递到所有部门。

Tarjan_mod或者Kosaraju_mod都能过,裸的强连通分量。

1:Kosaraju

#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxm 100010
#define maxn 50010
#define inf 1<<29
int belong[maxn],head[maxn],head2[maxn],vis[maxn],dfn[maxn],dis[maxn];
int ecnt,cnt,sum,n,m,ans;
using namespace std;
struct edge{
int u,v,next,w;
}E[maxm],Ee[maxm];
void addedge(int u,int v,int w)
{
E[++ecnt].u=u;
E[ecnt].v=v;
E[ecnt].w=w;
E[ecnt].next=head[u];
head[u]=ecnt;
Ee[ecnt].u=v;
Ee[ecnt].v=u;
Ee[ecnt].w=w;
Ee[ecnt].next=head2[v];
head2[v]=ecnt;
}
void dfs(int x)
{
for(int i = head[x] ; i ; i = E[i].next)
{
int v=E[i].v;
if(!vis[v])
{
vis[v]=;
dfs(v);
}
}
dfn[++cnt]=x;
return ;
}
void search(int x)
{
for(int i = head2[x] ; i ; i = Ee[i].next)
{
int v=Ee[i].v;
if(!belong[v])
{
belong[v]=sum;
search(v);
}
}
return ;
}
void kasa()
{
cnt=;
for(int i = ; i <= n ; ++i)
if(!vis[i])
{
vis[i]=;
dfs(i);
}
for(int i = cnt ; i >= ; --i)
{
int x=dfn[i];
if(!belong[x])
{
belong[x]=++sum;
search(x);
}
}
}
void init()
{
ecnt=cnt=sum=ans=;
memset(vis,,sizeof(vis));
memset(dfn,,sizeof(dfn));
memset(belong,,sizeof(belong));
memset(head,,sizeof(head));
memset(head2,,sizeof(head2));
for(int i = ; i <= maxn ; ++i)dis[i]=inf;
}
int main()
{
int a,b,w;
while(scanf("%d%d",&n,&m)&&n&&m)
{
init();
for(int i = ; i <= m ; ++i)
{
scanf("%d%d%d",&a,&b,&w);
addedge(a+,b+,w);
}
kasa();
for(int i = ; i <= m ; ++i)
{
for(int j = head[i] ; j ; j = E[j].next)
{
int u=E[j].u;
int v=E[j].v;
int w=E[j].w;
if(belong[u]!=belong[v])dis[belong[v]]=min(dis[belong[v]],w);
}
}
for(int i = ; i <= sum ; ++i)
{
if(dis[i]==inf)dis[i]=;
ans+=dis[i];
}
printf("%d\n",ans);
}
return ;
}

2、Tarjan

#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 100010
#define maxm 50010
#define inf 1<<29
using namespace std;
int instack[maxm],stack[maxm],belong[maxm],dfn[maxm],low[maxm],head[maxm],dis[maxm];
int ecnt,cnt,ans,ord,top;
struct edge{
int u,v,next,w;
}E[maxn];
void addedge(int u,int v,int w)
{
E[++ecnt].u=u;
E[ecnt].v=v;
E[ecnt].w=w;
E[ecnt].next=head[u];
head[u]=ecnt;
}
void Tarjan(int x)
{
dfn[x]=low[x]=++ord;
stack[++top]=x;
instack[x]=;
for(int i = head[x] ; i ; i = E[i].next)
{
int v=E[i].v;
if(!dfn[v])Tarjan(v);
if(instack[v])low[x]=min(low[v],low[x]);
}
if(dfn[x]==low[x])
{
++cnt;
int v;
do{
v=stack[top--];
instack[v]=;
belong[v]=cnt;
}while(x!=v);
}
}
void init()
{
top=ecnt=cnt=ans=ord=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(E,,sizeof(E));
memset(belong,,sizeof(belong));
memset(head,,sizeof(head));
memset(instack,,sizeof(instack));
memset(stack,,sizeof(stack));
for(int i = ; i <= maxm ; ++i)dis[i]=inf;
}
int main()
{
int n,m,a,b,w;
while(scanf("%d%d",&n,&m)&&n&&m)
{
init();
for(int i = ; i <= m ; ++i)
{
scanf("%d%d%d",&a,&b,&w);
addedge(a+,b+,w);
}
for(int i = ; i <= n ; ++i)
if(!dfn[i])Tarjan(i);
for(int i = ; i <= n ; ++i)
for(int j = head[i] ; j ; j = E[j].next)
{
int v=E[j].v;
int w=E[j].w;
if(belong[i]!=belong[v])dis[belong[v]]=min(dis[belong[v]],w);
}
for(int i = ; i <= cnt ; ++i)
{
if(dis[i]==inf)dis[i]=;
ans+=dis[i];
}
printf("%d\n",ans);
}
return ;
}

3.label (label.cpp/c/pas)

【问题描述】 Samjia和Peter不同,他喜欢玩树。所以Peter送给他一颗大小为n的树,节 点编号从1到n。 Samjia要给树上的每一个节点赋一个[1,m]之间的权值,并使得有边直接相 连的两个节点的权值之差的绝对值 ≥ k。请你告诉Samjia有多少种不同的赋值 方案,只用求出答案对10 9+7(1000000007)取模得到的结果。

【输入格式】 输入文件名为 label.in。 输入数据的第一行包含一个整数 T,代表测试数据组数。 接下来是 T 组数据. 每组数据的第一行包含三个整数 n、m 和 k。 接下来 n − 1 行,每行包含两个整数 u 和 v, 代表节点 u 和 v 之间有 一条树边。

【输出格式】 输出文件名为 label.out。 对于每组数据,输出一行,包含一个整数,代表所求的答案。

树形DP(mmp...)

注释写在代码里

#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define maxn 105
#define maxm 10005
#define mod 1000000007
using namespace std;
int f[maxn][maxm];
int T,n,m,k,lim,ecnt;
int head[maxn];
struct edge{
int u,v,next;
}E[maxn<<];
void addedge(int u,int v)//邻接表
{
E[++ecnt].u=u;
E[ecnt].v=v;
E[ecnt].next=head[u];
head[u]=ecnt;
}
ll getsum(int x,int from)
{
ll ret();
for(int i = from;i <= lim ; ++i)ret=(ret+f[x][i]%mod)%mod;遍历dp左端情况
for(int i = m ; i >= m-lim+ ; --i)//遍历dp右端情况
{
if(i<=lim||i<from)break;//防止i左移超出dp右端范围
ret=(ret+f[x][m-i+]%mod)%mod;//加上右端对应的dp左端值
}
int l=max(from,lim+),r=m-lim;//max是为了处理from大于lim+1的情况
int flg=r-l+;
if(flg>)ret=(ret+1ll*flg*f[x][lim]%mod)%mod;//中间所有值相同,存在lim里即可
return ret;
}
void dfs(int u,int fa)
{
for(int i = ; i <= lim ; ++i)f[u][i]=;
for(int i = head[u] ; i ; i = E[i].next)
{
int v= E[i].v;
if(v==fa)continue;
dfs(v,u);//建树
ll sum=getsum(v,k+);//对于父亲节点选1的情况进行初始化,通过右移过程中减去右端的值,增加左端的值实现动态变化。
for(int j = ; j <= lim ; ++j)
{
if(j-k>=)sum=(sum+f[v][j-k]%mod)%mod;//加上新加入的左端值
f[u][j]=1ll*sum*f[u][j]%mod;//乘法原理
if(j+k<=m)//右端不出界
{
int bb=j+k;
if(m-bb+<=lim)bb=m-bb+;//右端对应到lim左边,把右端对应到左端对称位置。
else if(bb>=lim)bb=lim;右端对应到lim右边,把右端转移至lim位置
sum=(sum-f[v][bb]+mod)%mod;//减去右边进入k范围内的值
}
}
}
}
int ksm(int x,int y)
{
int a=x%mod;
int ret();
while(y)
{
if(y&)ret=1ll*ret*a%mod;
y>>=;
a=1ll*a*a%mod;
}
return ret;
}
int main()
{
int a,b;
scanf("%d",&T);
while(T--)
{
ecnt=;
memset(head,,sizeof(head));
scanf("%d%d%d",&n,&m,&k);
for(int i = ; i < n ; ++i)
{
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
}
if(!k)//如果K为0,计算m^n即可
{
printf("%d\n",ksm(m,n));
continue;
}
lim=min(,m);//推导在下面
dfs(,);
printf("%I64d\n",getsum(,));
}
return ;
}

lim的推导:

借助样例

Dp[3][1]=dp[3][2]=……=dp[3][10]=1

Dp[2][1]=dp[2][10]=8

Dp[2][2]=dp[2][3]=……=dp[2][9]=7

Dp[1][1]=dp[1][10]=57

Dp[1][2]=dp[1][9]=50

Dp[1][3]=dp[1][4]=……=dp[1][8]=51

同一个点的 dp 值是对称的。 中间有一段的值是相同的。

树的最大深度n-1=99

因为k<=100所以某一端不同的值最多有9900个,简记成10000。

整体思路就是把f[v][i]中的左端实化,右端虚化,在做右端时通过左端对应位置来更新,然后把中间相同部分一并处理。

noip冲刺赛第五次考试的更多相关文章

  1. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  2. NOIP模拟赛-2018.11.7

    NOIP模拟赛 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 编译之前另存一份,听说如果敲 ...

  3. 10.17 NOIP模拟赛

    目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...

  4. 10.16 NOIP模拟赛

    目录 2018.10.16 NOIP模拟赛 A 购物shop B 期望exp(DP 期望 按位计算) C 魔法迷宫maze(状压 暴力) 考试代码 C 2018.10.16 NOIP模拟赛 时间:2h ...

  5. NOIP模拟赛-2018.11.6

    NOIP模拟赛 今天想着反正高一高二都要考试,那么干脆跟着高二考吧,因为高二的比赛更有技术含量(我自己带的键盘放在这里). 今天考了一套英文题?发现阅读理解还是有一些困难的. T1:有$n$个点,$m ...

  6. NOIP模拟赛-2018.11.5

    NOIP模拟赛 好像最近每天都会有模拟赛了.今天从高二逃考试跑到高一机房,然而高一也要考试,这回好像没有拒绝的理由了. 今天的模拟赛好像很有技术含量的感觉. T1:xgy断句. 好诡异的题目,首先给出 ...

  7. Nescafe #29 NOIP模拟赛

    Nescafe #29 NOIP模拟赛 不知道这种题发出来算不算侵权...毕竟有的题在$bz$上是权限题,但是在$vijos$似乎又有原题...如果这算是侵权的话请联系我,我会尽快删除,谢谢~ 今天开 ...

  8. 【HHHOJ】NOIP模拟赛 捌 解题报告

    点此进入比赛 得分: \(30+30+70=130\)(弱爆了) 排名: \(Rank\ 22\) \(Rating\):\(-31\) \(T1\):[HHHOJ260]「NOIP模拟赛 捌」Dig ...

  9. NOIp模拟赛二十八

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

随机推荐

  1. 【Android Developers Training】 104. 接受地点更新

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  2. 一张图告诉你angular2所有知识点

    忙活了半年,从angular2.0到现在angular4.2.从没AOT到有AOT.我想说,angular2的学习曲线真的有点陡峭.只能说,angular2是一个比较完整的框架,框架就是这样,一大堆条 ...

  3. KBEngine WebConsole Guide

    https://github.com/kbengine/kbengine/tree/master/docs

  4. 简约的HTML5音乐播放器插件

    从我刚开始接触前端的时候就想写一个能播放音乐的小程序,刚开始写的时候虽然可以放,但是确实很慢,很卡,有很多可以优化的地方.最近在前一个版本的基础上重写了一个音乐播放器的插件,速度还可以吧 因为追求简约 ...

  5. windows安装程序无法将windows配置为在此计算机的硬件上运行

    关于装windows系统时,出现一些安装中断的处理 该方法适用于 windows安装程序无法将windows配置为在此计算机的硬件上运行 计算机意外地重新启动或遇到错误. Windows 安装无法继续 ...

  6. PHP实现跨域解决方法

    如果要实现跨域通过设置Access-Control-Allow-Origin来实现跨域. 例如:客户端的域名是client.runoob.com,而请求的域名是server.runoob.com. 如 ...

  7. solr6.3 + Hbase Indexer使用MR创建索引,错误Bad return type

    使用solr6.3 + Hbase Indexer ,通过Hbase-indexer从Hbase建立索引到solr中,进行全文搜索. 两种实现方式:① 开启hbase-indexer进行实时同步新数据 ...

  8. JQuery学习笔记——层级选择器

    JQuery学习笔记--层级选择器 上一篇学习了基础的五种选择,分别是id选择器,class选择器,element选择器,*选择器 和 并列选择器.根据手册大纲,这篇学习的是层级选择器. 选择器: 1 ...

  9. Python基础之字符编码

    前言 字符编码非常容易出问题,我们要牢记几句话: 1.用什么编码保存的,就要用什么编码打开 2.程序的执行,是先将文件读入内存中 3.unicode是父编码,只能encode解码成其他编码格式 utf ...

  10. http调用端HttpClient、DefaultHttpClient、CloseableHttpClient

    1:说下httpClient接口和4.2.6版本后过时实例DefaultHttpClient,以及新的实例应用.  说到HTTP,脑子就冒出它的特性,基于TCP协议,简短点:说明是交互性的. 2:下面 ...