/*
可以并查集维护
可以发现,某个联通快出现大于等于2个环,一定无法分配。
有解要么一个环,要么没有环。
一个环时答案等于点数乘2(顺时针或逆时针)。
没有环是树,对于一个n个点的树,方案一定有n种(不连某个点)。
*/
#include<iostream>
#include<cstdio>
#include<cstring> #define N 100007
#define mod 1000000007
#define ll long long using namespace std;
ll n,m,ans,cnt;
ll fa[N],siz[N],num[N];
bool vis[N]; inline ll read()
{
ll x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} ll find(ll x){return x==fa[x]?x:fa[x]=find(fa[x]);} void merge(ll x,ll y)
{
fa[y]=x;
siz[x]+=siz[y];num[x]+=num[y];
} int main()
{
ll x,y;ans=;
n=read();m=read();
for(ll i=;i<=n;i++) fa[i]=i,siz[i]=;
for(ll i=;i<=m;i++)
{
x=read();y=read();
ll r1=find(x),r2=find(y);
if(r1!=r2) merge(r1,r2);
else num[r1]++;
}
for(ll i=;i<=n;i++)
{
ll now=find(i);
if(vis[now]) continue;vis[now]=;
if(num[now]>) continue;
if(num[now]==) ans=(ans*)%mod;
if(!num[now]) ans=(ans*siz[now])%mod;
}
printf("%lld\n",ans%mod);
return ;
}

/*
若两数k进制下相同
那么k进制后它们一定偶数位为0,奇数位为0~k-1
从高位递推可能的情况累加答案即可。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath> #define N 100
#define ll long long using namespace std;
ll n,k,ans,cnt,len;
ll Pow[N];
int a[N]; int main()
{
scanf("%lld%lld",&n,&k);
while(n){Pow[++len]=n%k;n/=k;}
if(len%==)
{
ans=pow(k,len>>);
printf("%lld\n",ans);
}
else
{
for(int i=len;i>=;i--)
{
if(Pow[i])
{
if(i%==)
{
ans+=1ll*pow(k,i/);
break;
}
else ans+=1ll*Pow[i]*pow(k,i/);
if(i==) ++ans;
}
}
}
printf("%lld\n",ans);
return ;
}

旅行

/*
嗯,需要维护每个点到根的距离。
首先开始的时候选取叶子结点一定比中间节点优。
当选择了一条链的时候,会对哪些点有影响呢?
答案当然是在这条链上的点的子树。把这个点的子树权值减掉这个点的权值就好。
看到子树,想到dfs序。又因为要查询最大值,所以可以想到用线段树实现。
线段树每个节点维护原树每个点到根的距离的最大值和原树每个节点dfs序所对应的点的编号。
每次查询区间最大值,然后删去这条链,每次删的时候更新子树权值(区间减法)。
删除把这个点的权值赋值为0就好。然后往上走,走的时候到某个点权值为0那么就停。
因为如果某个点权值为0,那么他到根的路径上所有点权都为零。恩。
*/
#include<iostream>
#include<cstdio>
#include<cstring> #define N 200007
#define ll long long using namespace std;
ll n,m,ans,cnt,tot;
ll head[N],dis[N],fa[N];
ll S[N],pos[N],T[N],a[N];
struct edge{
int u,v,net,w;
}e[N<<];
struct tree{
ll l,r,mx,pos,flag;
}tr[N<<]; namespace seg
{
void pushup(int k)
{
if(tr[k<<].mx>tr[k<<|].mx) tr[k].mx=tr[k<<].mx,tr[k].pos=tr[k<<].pos;
else tr[k].mx=tr[k<<|].mx,tr[k].pos=tr[k<<|].pos;
}
void pushdown(int k)
{
tr[k<<].flag+=tr[k].flag;tr[k<<|].flag+=tr[k].flag;
tr[k<<].mx+=tr[k].flag;tr[k<<|].mx+=tr[k].flag;
tr[k].flag=;
}
void build(int k,int l,int r)
{
tr[k].l=l;tr[k].r=r;
if(l==r)
{
tr[k].mx=dis[pos[l]],tr[k].pos=pos[l];
return;
}
int mid=l+r>>;
build(k<<,l,mid);build(k<<|,mid+,r);
pushup(k);
}
void update(int k,int l,int r,int z)
{
if(tr[k].l==l && tr[k].r==r)
{
tr[k].mx+=z;tr[k].flag+=z;
return;
}
pushdown(k);
int mid=tr[k].l+tr[k].r>>;
if(r<=mid) update(k<<,l,r,z);
else if(l>mid) update(k<<|,l,r,z);
else update(k<<,l,mid,z),update(k<<|,mid+,r,z);
pushup(k);
} }using namespace seg; inline void add(int u,int v)
{
e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt;
} inline ll read()
{
ll x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} void dfs(int u,int last,ll sum)
{
S[u]=++tot;pos[tot]=u;dis[u]=sum;
for(int i=head[u];i;i=e[i].net)
{
int v=e[i].v;
if(v==last) continue;
fa[v]=u;dfs(v,u,sum+a[v]);
}T[u]=tot;
} void change(int u)
{
while(a[u])
{
update(,S[u],T[u],-a[u]);
a[u]=;u=fa[u];
}
} int main()
{
freopen("tour.in","r",stdin);
freopen("tour.out","w",stdout);
int x,y;
n=read();m=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<n;i++)
{
x=read();y=read();
add(x,y);add(y,x);
}ans=a[];a[]=;dfs(,,);
build(,,n);
while(m--)
{
tree Tr=tr[];ans+=Tr.mx;
change(Tr.pos);
}
printf("%lld\n",ans);
return ;
}

清北考前刷题day3下午好的更多相关文章

  1. 清北考前刷题day1下午好

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

  2. 清北考前刷题da7下午好

    三向城 /* 原图一定是一棵完全二叉树. 根节点是x,左节点是x*2,右节点是x*2+1 转化为二进制往左右走就很明显了. */ #include<iostream> #include&l ...

  3. 清北考前刷题day6下午好

    /* 贪心 负数一定不取 枚举最高位是1 且答案取为0的 位置, 更新答案. */ #include<iostream> #include<cstdio> #include&l ...

  4. 清北考前刷题da5下午好

    /* (4,1)*(3,1)*(2,1)的话1变成2然后一直是2 2变成1然后变成3 3变成1然后变成4 4变成1 */ #include<iostream> #include<cs ...

  5. 清北考前刷题day4下午好

    /* 辗转相除,每次计算多出现了几个数. */ #include<iostream> #include<cstdio> #include<cstring> #inc ...

  6. 清北考前刷题day2下午好

    #include<iostream> #include<cstdio> #include<cstring> #include<stack> #defin ...

  7. 清北考前刷题day4早安

      LI /* 没有考虑次大值有大于一个的情况 */ #include<iostream> #include<cstdio> #include<cstring> # ...

  8. 清北考前刷题day7早安

  9. 清北考前刷题day6早安

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

随机推荐

  1. manacher模板整理

    //p[]为最长回文半径长度,id为当前最靠右端回文串的中心点(多个取最靠左),mx为id对应的回文串的最右端坐标+1void manacher(char *s,int len){ p[] = ; , ...

  2. [luoguP1082] 同余方程(扩展欧几里得)

    传送门 ax≡1(mod b) 这个式子就是 a * x % b == 1 % b 相当于 a * x - b * y == 1 只有当 gcd(a,b) == 1 时才有解,也就是说 ax + by ...

  3. 【HDOJ6148】Valley Numer(数位DP)

    题意: 1≤T≤200 ● 1≤length(N)≤100 思路: 设f[i,j,k,l]为第i位为j,前i位是否贴上限(0/1),递减或递增(0/1)方案数 g[i,j,k]为不到n位,第i位为j, ...

  4. python爬虫实现原理

    前言 简单来说互联网是由一个个站点和网络设备组成的大网,我们通过浏览器访问站点,站点把HTML.JS.CSS代码返回给浏览器,这些代码经过浏览器解析.渲染,将丰富多彩的网页呈现我们眼前: 一.爬虫是什 ...

  5. muduo定时器、多线程模型及epoll的封装

    timerfd是Linux为用户程序提供的一个定时器接口,这个接口基于文件描述符. clock_gettime函数可以获取系统时钟,精确到纳秒.需要在编译时指定库:-lrt.可以获取两种类型时间: C ...

  6. Elasticsearch学习系列之介绍安装

    前言 关于ELK搭建的问题,或许你还有些模糊,其实你把我视频里讲的知识点串联起来就明白了.搭建ELK环境,看下面我说的: 首先,先把ES集群搭建起来,建议用CentOS6.5 64位的linux系统, ...

  7. C# .NET using ManagementObjectSearcher提示缺少引用怎么办

    在下图中,即使引用了System.Management还是会出现报错   其实只要添加这条引用就可以了

  8. Unity3D 玻璃 Shader

     Shader "Custom/Glass" { // Upgrade NOTE: replaced 'SeperateSpecular' with 'SeparateSpec ...

  9. QlikView格式化某一个单元格

    QlikView中能够创建透视表和垂直表,或者一般的Table.假如有的时候须要某一个单元格的样式和其它单元格不一样.颜色或者边框宽度等.能够通过下面方式实现: 工具栏里面有个button叫:Desi ...

  10. “取出数据表中第10条到第20条记录”的sql语句+select top 使用方法

    1.首先.select top使用方法: 參考问题  select top n * from和select * from的差别 select * from table --  取全部数据.返回无序集合 ...