2017 清北济南考前刷题Day 3 afternoon
期望得分:100+40+100=240
实际得分:100+40+100=240
将每个联通块的贡献乘起来就是答案
如果一个联通块的边数>点数 ,那么无解
如果边数=点数,那么贡献是 2
如果边数=点数-1,那么贡献是点数
#include<queue>
#include<cstdio>
#include<iostream> using namespace std; const int mod=1e9+; #define N 100001 int front[N],to[N<<],nxt[N<<],tot; bool vis[N]; int d[N]; queue<int>q; int ans=; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
d[v]++;
} bool bfs(int s)
{
while(!q.empty()) q.pop();
int p=,e=;
q.push(s); vis[s]=true;
int now;
while(!q.empty())
{
now=q.front(); q.pop();
p++; e+=d[now];
for(int i=front[now];i;i=nxt[i])
if(!vis[to[i]]) vis[to[i]]=true,q.push(to[i]);
}
if(e>p) return false;
if(e==p) ans=ans*%mod;
else ans=1ll*ans*p%mod;
return true;
} int main()
{
freopen("girl.in","r",stdin);
freopen("girl.out","w",stdout);
int n,m;
read(n); read(m);
int u,v;
for(int i=;i<=m;i++)
{
read(u); read(v);
add(u,v);
}
for(int i=;i<=n;i++)
if(!vis[i])
if(!bfs(i)) { cout<<; return ; }
cout<<ans;
return ;
}
显然的结论:
若一个数的K进制和-k进制相同
那么他的k进制/-k进制的偶数位一定是0
然后乱搞就好了
也可以数位DP
#include<iostream>
#include<cstdio>
#include<cmath> using namespace std; typedef long long LL; LL bit[]; int a[]; int main()
{
freopen("endless.in","r",stdin);
freopen("endless.out","w",stdout);
long long n;int k;LL ans=;
scanf("%I64d%d",&n,&k);
int len=;
while(n) a[++len]=n%k,n/=k;
if(!(len&))
{
ans=pow(1LL*k,len/);
cout<<ans;
}
else
{
for(int i=len;i>=;i--)
if(a[i])
{
if(!(i&)) { ans+=pow(1LL*k,i/); break; }
ans+=1LL*a[i]*pow(1LL*k,i/);
if(i==) ans++;
}
cout<<ans;
}
}
40暴力
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream> using namespace std; int fbit[]; int a[],b[]; int pre[]; int main()
{
freopen("endless.in","r",stdin);
freopen("endless.out","w",stdout);
int n,k;
scanf("%d%d",&n,&k);
fbit[]=;
int la,lb; int x,ans=min(k-,n)+;
for(int i=k;i<=n;i++)
{
la=;
x=i;
while(x) a[la++]=x%k,x/=k; la--;
x=i;
int c=-,now=;
pre[]=k-;
while()
{
fbit[++now]=fbit[now-]*c*k;
if(!(now&))
{
pre[now]=pre[now-]+(k-)*fbit[now];
if(pre[now]>=x) break;
}
else pre[now]=pre[now-];
}
lb=now;
memset(b,,sizeof(b));
while(now)
{
if(!(now&)) while(x>pre[now-]) b[now]++,x-=fbit[now];
else
{
while(x< && abs(x)>pre[now-]) b[now]++,x-=fbit[now];
while(x>pre[now-]) b[now]++,x+=fbit[now];
}
now--;
}
b[]=x;
if(la!=lb) continue;
bool ok=true;
for(int i=;i<=la && ok ;i++) if(a[i]!=b[i]) ok=false;
if(!ok) continue;
// printf("%d\n",i);
ans++;
}
cout<<ans;
}
考场思路:
每次旅行一定是找当前贡献最大的叶子节点
用线段树维护所有的叶子节点的贡献
修改:
每个点只会修改一次
所以用并查集记录这个点到根节点路径上第一个没有被修改的点
修改沿着并查集的father找上去
对于每个要改的点,预处理出它会影响到的叶子节点,
按dfs到的叶子节点的顺序在线段树中加点,那每个点影响到的叶子节点就是一段连续的区间
dfs记下来,线段树区间修改即可
其实可以不用并查集
往上改到已经改过的点,直接break
#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 100001 typedef long long LL; int n,m;
int val[N]; int front[N],nxt[N<<],to[N<<],tot; int F[N],fa[N],id[N]; int cnt,L[N],R[N]; LL w[N]; LL mx[N<<],pos[N<<],tag[N<<]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
} void init()
{
read(n); read(m);
for(int i=;i<=n;i++) read(val[i]);
int u,v;
for(int i=;i<n;i++)
{
read(u); read(v);
add(u,v);
}
} void dfs(int x,int f,LL sum)
{
L[x]=cnt+;
F[x]=x; bool leaf=true;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=f) leaf=false,fa[to[i]]=x,dfs(to[i],x,sum+val[to[i]]);
if(leaf) w[++cnt]=sum,id[cnt]=x;
R[x]=cnt;
} void build(int k,int l,int r)
{
if(l==r) { mx[k]=w[l]; pos[k]=l; return; }
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
mx[k]=max(mx[k<<],mx[k<<|]);
pos[k]= mx[k]==mx[k<<] ? pos[k<<] : pos[k<<|];
} void down(int k)
{
mx[k<<]-=tag[k];
mx[k<<|]-=tag[k];
tag[k<<]+=tag[k];
tag[k<<|]+=tag[k];
tag[k]=;
} void change(int k,int l,int r,int opl,int opr,LL sum)
{
if(l>=opl && r<=opr)
{
mx[k]-=sum;
tag[k]+=sum;
return;
}
if(tag[k]) down(k);
int mid=l+r>>;
if(opl<=mid) change(k<<,l,mid,opl,opr,sum);
if(opr>mid) change(k<<|,mid+,r,opl,opr,sum);
mx[k]=max(mx[k<<],mx[k<<|]);
pos[k]=mx[k]==mx[k<<] ? pos[k<<] : pos[k<<|];
} int find(int i) { return F[i]==i ? i : F[i]=find(F[i]); } void solve()
{
int p; LL ans=;
while(m--)
{
p=id[pos[]]; // 第pos个叶子节点
ans+=mx[];
while(p)
{
change(,,cnt,L[p],R[p],val[p]);
F[p]=find(F[fa[p]]);
p=F[p];
}
}
cout<<ans;
} int main()
{
freopen("tour.in","r",stdin);
freopen("tour.out","w",stdout);
init();
dfs(,,val[]);
build(,,cnt);
solve();
}
2017 清北济南考前刷题Day 3 afternoon的更多相关文章
- 2017 清北济南考前刷题Day 7 afternoon
期望得分:100+100+30=230 实际得分:100+100+30=230 1. 三向城 题目描述 三向城是一个巨大的城市,之所以叫这个名字,是因为城市中遍布着数不尽的三岔路口.(来自取名力为0的 ...
- 2017 清北济南考前刷题Day 1 afternoon
期望得分:80+30+70=180 实际得分:10+30+70=110 T1 水题(water) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK出了道水 ...
- 2017 清北济南考前刷题Day 4 afternoon
期望得分:30+50+30=110 实际得分:40+0+0=40 并查集合并再次写炸... 模拟更相减损术的过程 更相减损术,差一定比被减数小,当被减数=减数时,停止 对于同一个减数来说,会被减 第1 ...
- 2017 清北济南考前刷题Day 6 afternoon
期望得分:100+100+30=230 实际得分: 正解: 枚举最高的位,这一位m是1但实际用了0 然后剩余的低位肯定是 正数就用1,负数用0 考场思路:数位DP #include<cstdio ...
- 2017 清北济南考前刷题Day 5 afternoon
期望得分:100+100+30=230 实际得分:0+0+0=30 T1 直接模拟 #include<cstdio> #include<iostream> using name ...
- 2017 清北济南考前刷题Day 2 afternoon
期望得分:100+60+70=230 实际得分:0+60+0=60 T1 可以证明如果一对括号原本就匹配,那么这对括号在最优解中一定不会被分开 所以用栈记录下没有匹配的括号 最后栈中一定是 一堆右括号 ...
- 2017 清北济南考前刷题Day 3 morning
实际得分:100+0+0=100 T1 右上角是必败态,然后推下去 发现同行全是必胜态或全是必败态,不同行必胜必败交叉 列同行 所以n,m 只要有一个是偶数,先手必胜 #include<cstd ...
- 2017 清北济南考前刷题Day 7 morning
期望得分:100+50+20=170 实际得分:10+50+20=80 1. 纸牌 题目描述 在桌面上放着n张纸牌,每张纸牌有两面,每面都写着一个非负整数.你的邪王真眼可以看到所有牌朝上的一面和朝下的 ...
- 2017 清北济南考前刷题Day 6 morning
T1 贪心 10 元先找5元 20元 先找10+5,再找3张5 #include<cstdio> using namespace std; int m5,m10,m20; int main ...
随机推荐
- JDK 9.0.4安装过程
因为种种问题,怀疑是因为JDK版本不对劲,于是打算将JDK重新搞一下. 不看不知道,看了吓一跳,我的笔记本里现在起码有5.6甚至更多个JDK,JRE,并且由于年久失修,我也不知道这些东西怎么装上去的, ...
- 【CF17E】Palisection(回文树)
[CF17E]Palisection(回文树) 题面 洛谷 题解 题意: 求有重叠部分的回文子串对的数量 所谓正难则反 求出所有不重叠的即可 求出以一个位置结束的回文串的数量 和以一个位置为开始的回文 ...
- 【BZOJ2729】【HNOI2012】排队(组合数学)
不想弄题面了... 题解 做这道题目我真的好蠢... 好容易的数学题目 很明显自己写高精度吧...(不解释了) 剩下的如何计算. 要有两类情况 ①老师之间有男生 那么,这种情况下,直接插空就行了 先把 ...
- Vue-开发工具的安装
1. github官网下载vue工具:https://github.com/vuejs/vue-devtools.并解压 2. 在有package.json的文件夹下,按住shift右键,选择&qu ...
- iOS开发--XMPPFramework--好友列表(五)
上一篇文章,我们讨论了调试和好友模块,这一篇,在引入了好友模块后,我们来说说好友列表的显示. 还记得在上一篇中,我们把自动拉去好友列表给关掉了,所以,我们选择在控制器的-(void)viewDidLo ...
- Vue的组件为什么要export default
Vue 的模块机制 Vue 是通过 webpack 实现的模块化,因此可以使用 import 来引入模块,例如: 此外,你还可以在bulid/webpack.base.conf.js文件中修改相关配置 ...
- 4.2 js没有块级作用域
JavaScript没有块级作用域.在其他语言上,比如C语言中,有花括号封闭的代码块都有自己的作用域,(如果用ECMAScript的话来讲,就是他们自己的执行环境),因而支持根据条件来定义变量.例如, ...
- 微信小程序之生成图片分享
通过社交软件分享的方式来进行营销小程序,是一个常用的运营途径.小程序本身支持直接将一个小程序的链接卡片分享至微信好友或微信群,然后别人就可以通过点击该卡片进入该小程序页面.但是小程序目前不支持直接分享 ...
- 01背包问题(Java实现)
关于背包问题,百度文库上有崔添翼大神的<背包九讲>,不明的请移步查看.这里仅介绍最基本的01背包问题的实现. public class Knapsack { private final i ...
- VLOOKUP和MATCH嵌套以高效引用多列数据
VLOOKUP函数在日常工作中十分常见,以至于你要是没用过VLOOKUP函数,你都不好意思说你懂EXCEL. 一般情况下,我们需要在源数据中查找某个指定列的数据,就会用到VLOOKUP函数(如果是指定 ...