清北刷题冲刺 10-30 p.m
少女
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstdlib>
#define maxn 200010
#define mod 1000000007
using namespace std;
int n,m,head[maxn],num,c[maxn],du[maxn];
int ans=;
bool vis[maxn];
struct node{
int to,pre,v;
}e[maxn*];
void Insert(int from,int to,int id,int v){
e[id].to=to;
e[id].v=v;
e[id].pre=head[from];
head[from]=id;
}
int Pow(int a,int b){
int res=;
while(b){
if(b&)res=1LL*res*a%mod;
a=1LL*a*a%mod;
b>>=;
}
return res;
}
void bfs(int s){
int count=;
queue<int>q;
q.push(s);vis[s]=;
int cnt=;//记录联通块中有多少边
while(!q.empty()){
int now=q.front();q.pop();
count+=c[now];
while(count>=mod)count-=mod;
for(int i=head[now];i;i=e[i].pre){
if(e[i].v){
e[i].v=;
int nxt;
if(i>m)nxt=i-m;
if(i<=m)nxt=i+m;
e[nxt].v=;
cnt+=;
if(!vis[e[i].to]){
vis[e[i].to]=;
q.push(e[i].to);
}
}
}
}
int w=Pow(,cnt)-count;
if(w<=){
puts("");exit();
}
ans=1LL*ans*w%mod;
while(ans>=mod)ans-=mod;
}
int main(){
freopen("girl.in","r",stdin);freopen("girl.out","w",stdout);
// freopen("Cola.txt","r",stdin);
scanf("%d%d",&n,&m);
int x,y;
for(int i=;i<=m;i++){
scanf("%d%d",&x,&y);
if(x==y)y+=n,n++;
Insert(x,y,i,);Insert(y,x,i+m,);
du[x]++;du[y]++;
}
for(int i=;i<=n;i++){
c[i]=Pow(,du[i])--du[i];
while(c[i]<)c[i]+=mod;
}
for(int i=;i<=n;i++){
if(!vis[i]){
bfs(i);
}
}
printf("%d",ans);
return ;
}
0分
/*
对于图上每个联通块:
有>=2个环就无解;
有一个环就有2个解(顺时针和逆时针);
没有环,就是一棵树,n个点,n-1条边,所以有一个点没有边匹配,这个点有n种情况,所以有n个解
*/
#include<iostream>
#include<cstdio>
#define maxn 100010
#define mod 1000000007
using namespace std;
int n,m,x,y,fa[maxn],r[maxn],sz[maxn];
bool vis[maxn];
int find(int x){
if(x==fa[x])return x;
else return fa[x]=find(fa[x]);
}
int main(){
freopen("girl.in","r",stdin);freopen("girl.out","w",stdout);
// freopen("Cola.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)fa[i]=i,sz[i]=;
for(int i=;i<=m;i++){
scanf("%d%d",&x,&y);
int f1=find(x),f2=find(y);
if(f1==f2){
if(r[f1]){
puts("");
return ;
}
else r[f1]=;
}
else {
fa[f2]=f1;
r[f1]|=r[f2];
sz[f1]+=sz[f2];
sz[f2]=;
}
}
long long ans=;
for(int i=;i<=n;i++){
int father=find(i);
if(!vis[father]){
vis[father]=;
if(r[father])ans=2LL*ans%mod;
else ans=1LL*sz[father]*ans%mod;
}
}
cout<<ans;
return ;
}
100分 并查集判环
终末
#include<iostream>
#include<cstdio>
using namespace std;
long long n,bin[],ans,a[];
int k,cnt=-;
long long Pow(long long a,long long b){
long long res=;
while(b){
if(b&)res=1LL*res*a;
a=1LL*a*a;
b>>=;
}
return res;
}
int main(){
// freopen("Cola.txt","r",stdin);
// freopen("endless.in","r",stdin);freopen("endless.out","w",stdout);
cin>>n>>k;
int t=;
while(){
cnt=cnt+;
bin[cnt]=Pow(k,cnt);
if(bin[cnt]>n)break;
}
for(long long i=;i<=n;i++){
bool flag=;
long long now=i;
for(int j=cnt;j>=;j--){
a[j]=now/bin[j];
if(a[j]&&(j&)){
flag=;break;
}
now-=a[j]*bin[j];
}
if(flag==)ans++;
}
cout<<ans;
}
40分 暴力
/*
满足条件的数必须有一个性质,转成k进制后偶数位为0,奇数位为0~k-1
所以就是求<=n的数转化为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;
}
}
100分 数位dp
旅行
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 100010
using namespace std;
int n,num,head[maxn],v[maxn],k,le[maxn],cnt;
long long w[maxn],ans,sum;
int top[maxn],fa[maxn],son[maxn],sz[maxn],dep[maxn];
struct node{
int to,pre;
}e[maxn*];
void Insert(int from,int to){
e[++num].to=to;
e[num].pre=head[from];
head[from]=num;
}
void dfs1(int now,int father){
dep[now]=dep[father]+;
fa[now]=father;
sz[now]=;
w[now]=w[father]+v[now];
bool flag=;
for(int i=head[now];i;i=e[i].pre){
int to=e[i].to;
if(to==father)continue;
dfs1(to,now);
sz[now]+=sz[to];
if(!son[now]||sz[to]>sz[son[now]])son[now]=to;
flag=;
}
if(!flag)le[++cnt]=now;
}
void dfs2(int now,int father){
top[now]=father;
if(son[now])dfs2(son[now],father);
for(int i=head[now];i;i=e[i].pre){
int to=e[i].to;
if(to==fa[now]||to==son[now])continue;
dfs2(to,to);
}
}
int lca(int a,int b){
while(top[a]!=top[b]){
if(dep[top[a]]<dep[top[b]])swap(a,b);
a=fa[top[a]];
}
if(dep[a]>dep[b])swap(a,b);
return a;
}
int q[maxn];
void count(){
long long now=;
for(int i=;i<=k;i++)now+=w[q[i]];
for(int i=;i<=k;i++)
for(int j=i+;j<=k;j++)
now-=w[lca(q[i],q[j])];
ans=max(ans,now);
}
void dfs(int pos,int c){
if(c==k+){
count();
return;
}
if(pos>cnt)return;
if(cnt-pos<k-c)return;
q[c]=le[pos];
dfs(pos+,c+);
dfs(pos+,c);
}
bool flag=;
bool cmp(int x,int y){return x>y;}
int main(){
freopen("tour.in","r",stdin);freopen("tour.out","w",stdout);
// freopen("Cola.txt","r",stdin);
scanf("%d%d",&n,&k);
if(k==){
puts("");
return ;
}
int x,y;
for(int i=;i<=n;i++)scanf("%d",&v[i]),sum+=v[i];
for(int i=;i<n;i++){
scanf("%d%d",&x,&y);
Insert(x,y);Insert(y,x);
if(x!=&&y!=)flag=;
}
if(flag){
ans=v[];
v[]=;
sort(v+,v+n+,cmp);
for(int i=;i<=k;i++){
ans+=v[i];
}
cout<<ans;
return ;
}
dfs1(,);
dfs2(,);
if(k>=cnt){
cout<<sum;
return ;
}
dfs(,);
cout<<ans;
return ;
}
30分 暴力
/*
对树上的所有叶子节点到根的前缀和建一棵线段树,每次贪心选择前缀和最大的节点,并把路径上所有点为根节点的子树的叶子节点的前缀和减那个数,每次修改的都是一个连续的区间,所以可以用线段树的区间修改进行维护
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define maxn 100010
int n,m,val[maxn],head[maxn],num;
int opl,opr;long long opv;
struct node{
int to,pre;
}e[maxn*];
int F[maxn],fa[maxn],id[maxn],cnt,L[maxn],R[maxn];
long long w[maxn],mx[maxn<<],pos[maxn<<],tag[maxn<<];
void Insert(int from,int to){
e[++num].to=to;
e[num].pre=head[from];
head[from]=num;
}
void init(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&val[i]);
int x,y;
for(int i=;i<n;i++){
scanf("%d%d",&x,&y);
Insert(x,y);Insert(y,x);
}
}
void dfs(int now,int father,long long sum){
L[now]=cnt+;
F[now]=now;bool leaf=;
fa[now]=father;
for(int i=head[now];i;i=e[i].pre){
int to=e[i].to;
if(to==father)continue;
leaf=;
dfs(to,now,sum+val[to]);
}
if(leaf)w[++cnt]=sum,id[cnt]=now;
R[now]=cnt;
}
void build(int l,int r,int k){
if(l==r){mx[k]=w[l];pos[k]=l;return;}
int mid=(l+r)>>;
build(l,mid,k<<);
build(mid+,r,k<<|);
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){
if(opl<=l&&opr>=r){
mx[k]-=opv;
tag[k]+=opv;
return;
}
if(tag[k])down(k);
int mid=(l+r)>>;
if(opl<=mid)change(k<<,l,mid);
if(opr>mid)change(k<<|,mid+,r);
mx[k]=max(mx[k<<],mx[k<<|]);
pos[k]=(mx[k]==mx[k<<]?pos[k<<]:pos[k<<|]);
}
int find(int x){
if(x==F[x])return x;
return F[x]=find(F[x]);
}
void solve(){
int p;long long ans=;
while(m--){
p=id[pos[]];
ans+=mx[];
while(p){
opl=L[p];opr=R[p];opv=val[p];
change(,,cnt);
F[p]=find(F[fa[p]]);
p=F[p];
}
}
cout<<ans;
}
int main(){
freopen("tour.in","r",stdin);freopen("tour.out","w",stdout);
// freopen("Cola.txt","r",stdin);
init();
dfs(,,val[]);
build(,cnt,);
solve();
}
100分 线段树
预计得分100++
实际得分0++
T1错误比较大,是思路有误,根本原因在于自己造的样例没有包括全部的情况,以后引以为戒,不光要多造样例,更要尽可能想到更多的情况。T2T3写的时间不多,T2暴力分拿到了,T3wa了好几个,不知道为什么
今天下午时间把握不好,T1上浪费的时间太多而且思路偏离,T2T3草草写了暴力,难免出错,下不为例
小结
清北刷题冲刺 10-30 p.m的更多相关文章
- 清北刷题冲刺 10-30 a.m
星空 #include<iostream> #include<cstdio> using namespace std; int n,m; int main(){ freopen ...
- 清北刷题冲刺 10-28 p.m
水题(贪心) (water) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK出了道水题. 这个水题是这样的:有两副牌,每副牌都有n张. 对于第一副牌的每 ...
- 2017-10-4 清北刷题冲刺班p.m
P102zhx a [问题描述]你是能看到第一题的 friends 呢.——hja两种操作:1.加入一个数.2.询问有多少个数是?的倍数.[输入格式]第一行一个整数?,代表操作数量.接下来?行,每行两 ...
- 2017-10-4 清北刷题冲刺班a.m
P101zhx a [问题描述]你是能看到第一题的 friends 呢.——hjaHja 拥有一套时光穿梭技术,能把字符串以超越光速的速度传播,但是唯一的问题是可能会 GG.在传输的过程中,可能有四种 ...
- 2017-10-3 清北刷题冲刺班a.m
P99zhx a [问题描述]你是能看到第一题的 friends 呢.——hja怎么快速记单词呢?也许把单词分类再记单词是个不错的选择.何大爷给出了一种分单词的方法,何大爷认为两个单词是同一类的当这两 ...
- 2017-10-2 清北刷题冲刺班a.m
一道图论神题 (god) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只 ...
- 2017-10-2 清北刷题冲刺班p.m
最大值 (max) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有一本书,上面有很多有趣的OI问题.今天LYK看到了这么一道题目: 这里有一个长度为n ...
- 2017-10-1 清北刷题冲刺班p.m
一道图论好题 (graph) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图 ...
- 清北刷题冲刺 11-03 a.m
纸牌 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...
- 清北刷题冲刺 11-01 p.m
轮换 #include<iostream> #include<cstdio> #include<cstring> #define maxn 1010 using n ...
随机推荐
- 什么是 Sass 其与SCSS区别是什么?
Sass 官网上是这样描述 Sass 的: Sass 是一门高于 CSS 的元语言,它能用来清晰地.结构化地描述文件样式,有着比普通 CSS 更加强大的功能. Sass 能够提供更简洁.更优雅的语法, ...
- openlayers 3加载GeoServer发布的wfs类型服务
转:https://blog.csdn.net/u013323965/article/details/52449502 问题产生: openlayer3加载WFS存在跨域问题,需要用json ...
- 9 python 数据类型—字典
字典是python中唯一的映射类型,采用键值对(key-value)的形式存储数据.python对key进行哈希函数运算,根据计算的结果决定value的存储地址,所以字典是无序存储的,且key必须是可 ...
- linux命令学习笔记(22):find 命令的参数详解
find一些常用参数的一些常用实例和一些具体用法和注意事项. .使用name选项: 文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用. 可以使用某种文件名 模式来匹配文 ...
- android:layout_weight的真实含义/android:layout_gravity的条件
用layout_weight的时候,不要把宽度(或是高度,你想分配weight的那个)设成match_parent. android:layout_weight只适用于LinearLayout and ...
- CRtmpServer
1. 前言 crtmpserver是一个由C++语言编写的开源的RTMP流媒体服务器,官方网站是www.rtmpd.com 2. CRtmpServer编译 2.1. Win7+Vs201 ...
- 洛谷【P3952】NOIP2017提高组Day1T2时间复杂度
我对模拟的理解:http://www.cnblogs.com/AKMer/p/9064018.html 题目传送门:https://www.luogu.org/problemnew/show/P395 ...
- java多线程编程核心技术——第四章总结
第一节使用ReentrantLock类 1.1使用ReentrantLock实现同步:测试1 1.2使用ReentrantLock实现同步:测试2 1.3使用Condition实现等待/同步错误用法与 ...
- Poj 1077 eight(BFS+全序列Hash解八数码问题)
一.题意 经典的八数码问题,有人说不做此题人生不完整,哈哈.给出一个含数字1~8和字母x的3 * 3矩阵,如: 1 2 X 3 4 6 7 5 8 ...
- css画三角形
效果图: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...