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 ...
随机推荐
- [APIO2009]会议中心
[APIO2009]会议中心 题目大意: 原网址与样例戳我! 给定n个区间,询问以下问题: 1.最多能够选择多少个不相交的区间? 2.在第一问的基础上,输出字典序最小的方案. 数据范围:\(n \le ...
- NOIP提高组 2013货车运输
觉得题目水的离开 不屑的大佬请离开 不会图论的请离开 ……. 感谢您贡献的访问量 ————————————华丽的分割线———————————— 题面: 题目描述 A 国有 n 座城市,编号从 1 到 ...
- [BZOJ1041] [HAOI2008] 圆上的整点 (数学)
Description 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. Input 只有一个正整数n,n<=2000 000 000 Output 整点个数 Samp ...
- Net 面试随想
佳节已去,至今已半月有余,近来园中唱衰net的声音幽幽而起,net不成熟的大环境一直被作为诟病,net core的跨平台去年抄的火热,是否为net 崛起的最后一根稻草,结合我面试的情况,作为小白,嘟囔 ...
- git基本使用(搭建Git服务器)
我操作的是阿里的云服务器Linux系统的.系统不一样可能指令也不一样: 简要说明: git是分布式版本控制系统,也就是说每个开发人员的本地库和远程的库都是一样的. 基本思路: 1.在远程服务器上的一个 ...
- Micropython TurnipBit 青少年入门编程 交通灯实验
不知道大家小时候对红绿灯的原理有什么研究过,我是农村的孩子直到初中才见到真实的红绿灯,当时我记得很清楚,在那个路口站了五六分钟就盯着红绿灯变换,搞不清原理,只觉得神奇.现在想来实在可笑,今天写这个的很 ...
- ngrx/store effects 使用总结1:计数器
本教程案例github:https://github.com/axel10/ngrx_demo-counter-and-list angular2+ 的学习成本应该是三大框架中最高的一个,教程及案例稀 ...
- js实现二叉树
//binary tree//add order remove findfunction tree() { var node = function(key) { this.left = null; ...
- 使用text-overflow: ellipsis 处理文本溢的一个小问题
今天在做一个自定义 select多选 搜索的时候,有这样子的一个需求: 1.点击自定义的一个 选项内容框,下拉可多选项 2.多选项不允许换行,且父溢出拆剪,(单行)溢出部分使用 "...&q ...
- 【.NetCore】基于jenkins以及gitlab的持续编译及发布
前沿 其实本来是想把标题叫做持续集成的,只是后来看看研究出的内容,就只有发布这一个动作,自动化测试等内容也未涉及到,所以改名叫持续编译及发布应该更加贴切吧? 问题背景 其实目前我们传统方式上的发布方式 ...