少女

#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. Unity3D之Mesh【创建动态Mesh的学习网站】

    觉得不错!做记录! 1.http://gamerboom.com/archives/76484 2.http://jayelinda.com/ 3.几个私人的博客,可能有启发:http://blog. ...

  2. 更新github上代码

    前面一篇已经实现首次上传代码到github了,本篇继续讲如何把本地更新的代码同步更新到github上 一.clone代码 1.把大神的代码clone到本地,或者clone自己github上的代码,使用 ...

  3. python基础-变量

    1.什么是变量? 其实就是给数据起个名字而已.在python中你不想要关心数据类型,因为在你赋值的时候它已经自己帮你识别了 2.创建变量时候会在内存中开辟一个空间,具体的细节不需要咱们关心,解释器会分 ...

  4. java-StringBuffer常用方法

    对字符串进行修改的时候,需要使用可变长字符串StringBuffer 和 StringBuilder 类. append(String s):将指定的字符串追加到此字符序列. Reverse():将此 ...

  5. 基于DirectShow和FFmpeg的USB摄像头监控软件-转

    第一个版本 ### 软件版本及实现功能 0.0.1 1. USB摄像头枚举和设备信息获取2. 实时视频观看3. 24小时不间断录像,录像文件支持暴风影音播放 ### 软件说明: 软件基于 Direct ...

  6. bzoj 1242 弦图判定 MCS

    题目大意: 给定一张无向图,判断是不是弦图. 题解: 今天刚学了<弦图与区间图> 本来写了一个60行+的学习笔记 结果因为忘了保存重启电脑后被还原了... 那就算了吧. MCS最大势算法, ...

  7. 常用排序算法总结(C语言描述)

    最近又把排序给复(yu)习(xi)了一遍,在此总结一下~具体理论思想持续补充完善中... 1.交换排序 (1)普通冒泡 时间复杂度:最差.平均都是O(n^2),最好是O(n) 空间复杂度:O(1) # ...

  8. tomcat安装与运行

    实验环境:CentOS7 使用系统yum仓库安装: #安装基本包和开发工具包 [root@~ localhost]#yum install -y java-1.8.0-openjdk java-1.8 ...

  9. JVM类加载(2)—连接

    2.连接 连接就是将已经加载到内存中的类的二进制数据合并到Java虚拟机的运行时环境中去,加载阶段尚未完成,连接阶段可能已经开始.连接阶段包含验证.准备.解析过程. 2.1.验证 验证.class文件 ...

  10. asp弹出层

    asp弹出层 <style type="text/css"> html, body { height: %; width: %; } .white_content { ...