少女

#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的更多相关文章

  1. 清北刷题冲刺 10-30 a.m

    星空 #include<iostream> #include<cstdio> using namespace std; int n,m; int main(){ freopen ...

  2. 清北刷题冲刺 10-28 p.m

    水题(贪心) (water) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK出了道水题. 这个水题是这样的:有两副牌,每副牌都有n张. 对于第一副牌的每 ...

  3. 2017-10-4 清北刷题冲刺班p.m

    P102zhx a [问题描述]你是能看到第一题的 friends 呢.——hja两种操作:1.加入一个数.2.询问有多少个数是?的倍数.[输入格式]第一行一个整数?,代表操作数量.接下来?行,每行两 ...

  4. 2017-10-4 清北刷题冲刺班a.m

    P101zhx a [问题描述]你是能看到第一题的 friends 呢.——hjaHja 拥有一套时光穿梭技术,能把字符串以超越光速的速度传播,但是唯一的问题是可能会 GG.在传输的过程中,可能有四种 ...

  5. 2017-10-3 清北刷题冲刺班a.m

    P99zhx a [问题描述]你是能看到第一题的 friends 呢.——hja怎么快速记单词呢?也许把单词分类再记单词是个不错的选择.何大爷给出了一种分单词的方法,何大爷认为两个单词是同一类的当这两 ...

  6. 2017-10-2 清北刷题冲刺班a.m

    一道图论神题 (god) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只 ...

  7. 2017-10-2 清北刷题冲刺班p.m

    最大值 (max) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一本书,上面有很多有趣的OI问题.今天LYK看到了这么一道题目: 这里有一个长度为n ...

  8. 2017-10-1 清北刷题冲刺班p.m

    一道图论好题 (graph) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图 ...

  9. 清北刷题冲刺 11-03 a.m

    纸牌 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...

  10. 清北刷题冲刺 11-01 p.m

    轮换 #include<iostream> #include<cstdio> #include<cstring> #define maxn 1010 using n ...

随机推荐

  1. node.js+express+jade系列七:富文本编辑框的使用

    下载nicEdit富文本编辑框, 把nicEdit.js文件放到public/javascripts/下 新建jade文件:代码如下 doctype htmlhtml    head        t ...

  2. Python基础-set集合操作

    set集合,是一个无序且不重复的元素集合.定义方式类似字典使用{}创建 目前我们学过的数据类型: 1.字符串(str),2.整型(int),3.浮点型(float),4,列表(list) 5.元组(t ...

  3. numpy.ndarray类型的数组元素输出时,保留小数点后4位

    因为计算结果数组中每个值都是很长的一串小数,看起来比较乱,想格式化一下输出方式. 这是个看起来很简单的问题,但是方法找了很久. 方法也是看起来很简单,用 numpy.set_printoptions( ...

  4. 本地未安装Oracle数据库,如何连接远程Oracle数据库

    方法一:用Navicat Premium连接 注意,这里用的要是黄色的版本,而不是只针对Mysql的绿色版本 工具栏选择[工具]-[选项],点击[其他-OCI]    你会发现有个OCI librar ...

  5. BestCoder Round #92 比赛记录

    上午考完试后看到了晚上的BestCoder比赛,全机房都来参加 感觉压力好大啊QAQ,要被虐了. 7:00 比赛开始了,迅速点进了T1 大呼这好水啊!告诉了同桌怎么看中文题面 然后就开始码码码,4分1 ...

  6. JS之事件监听

    一 如果事件监听类似于如下写法,则最终只会执行最后一个事件监听,其他监听都会被覆盖掉. window.onload=funtion(){console.log(1);}; window.onload= ...

  7. 51nod 1250 排列与交换——dp

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1250 仔细思考dp. 第一问,考虑已知 i-1 个数有多少种方案. ...

  8. node.js的国内源

    node.js在使用npm安装包是,由于源是国外的,有可能会被GFW屏蔽. 通过下面的方法可以把源指向国内的. 具体方法如下: 编辑 ~/.npmrc 加入下面内容 registry = http:/ ...

  9. GPIO编程1:用文件IO的方式操作GPIO

    概述 通过 sysfs 方式控制 GPIO,先访问 /sys/class/gpio 目录,向 export 文件写入 GPIO 编号,使得该 GPIO 的操作接口从内核空间暴露到用户空间,GPIO 的 ...

  10. 【转】 Pro Android学习笔记(三一):Menu(2):扩展、图片、子菜单

    目录(?)[-] 菜单扩展 菜单项加入图片 子菜单 菜单扩展 如果菜单项很多,超过六个时,就会采用菜单扩展模式.在例子中我加入了10个菜单项,预计能进入菜单扩展模式,但是实际效果如右图所示.效果和li ...