题解:
记录树上前缀和,每次加入新前缀和就二分一下前缀和数组看有无满足\(sum[now]-s\)的数在里面,因为\(sum\)必定是单调的,就乱搞完毕;
\(code\):
#include<cstdio>
#include<algorithm>
#include<ctype.h>
#include<vector>
#include<queue>
#include<cstring>
#include<map>
#include<stdlib.h>
#include<ctime>
#define lowbit(x) (x&-x)
#define ll long long
#define ld double
#define mod 998244353
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
bool flag=0;
while(!isdigit(tt=gc())&&tt!='-');
tt=='-'?(flag=1,x=0):(x=tt-'0');
while(isdigit(tt=gc())) x=x*10+tt-'0';
if(flag) x=-x;
}
const int maxn=1e5+2;
int n,s;
vector<int>G[maxn];
bool root[maxn];
int w[maxn],sum[maxn],ans;
void dfs(int x,int dep)
{
sum[dep]=sum[dep-1]+w[x];
if(sum[lower_bound(
sum,sum+dep+1,sum[dep]-s)-sum]==sum[dep]-s) ans++;
for(int i=G[x].size()-1;i>=0;i--)
{
int p=G[x][i];
dfs(p,dep+1);
}
sum[dep]=0;
}
int main()
{
read(n),read(s);
for(int i=1;i<=n;i++) read(w[i]);
for(int i=1;i<n;i++)
{
int x,y;
read(x),read(y);
G[x].push_back(y);
root[y]=1;
}
for(int i=1;i<=n;i++)
if(!root[i]) {dfs(i,1);break;}
printf("%d",ans);
return 0;
}
题解:
树DP=_=
\(code:\)
#include<cstdio>
#include<algorithm>
#include<ctype.h>
#include<vector>
#include<queue>
#include<cstring>
#include<map>
#include<stdlib.h>
#include<ctime>
#define lowbit(x) (x&-x)
#define ll long long
#define ld double
#define mod 998244353
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
// return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
bool flag=0;
while(!isdigit(tt=gc())&&tt!='-');
tt=='-'?(flag=1,x=0):(x=tt-'0');
while(isdigit(tt=gc())) x=x*10+tt-'0';
if(flag) x=-x;
}
inline ll add(ll a,ll b){return a+b<mod?a+b:a+b-mod;}
inline ll mul(ll a,ll b){return a*b<mod?a*b:a*b%mod;}
inline ll sub(ll a,ll b){return a-b<0?a-b+mod:a-b;}
const int maxn=2002;
struct node{
ll x,id;
inline node(ll a=0,ll b=0)
{x=a,id=b;}
inline bool operator<(node a)const
{return x==a.x?a.id<a.id:x<a.x;}
}a[maxn];
ll n,k,ans,w[maxn];
vector<ll>G[maxn];
bool book[maxn];
ll dfs(ll x,ll pre,ll lim)
{
int ret=1;
for(int i=G[x].size()-1;i>=0;i--)
{
int p=G[x][i];
if(p==pre||book[p]||w[p]>lim) continue;
ret=mul(ret,dfs(p,x,lim));
}
// printf("%d\n",lim);
return ret+=(pre!=0);
}
int main()
{
read(n),read(k);
for(int i=1;i<=n;i++)
{
ll x;
read(x);w[i]=x;
a[i]=node(x,i);
}sort(a+1,a+1+n);
for(int i=1;i<n;i++)
{
ll x,y;
read(x),read(y);
G[x].push_back(y);
G[y].push_back(x);
}
for(int i=1;i<=n;i++)
{
if(book[a[i].id]) continue;
book[a[i].id]=1;
ans=add(ans,dfs(a[i].id,0,a[i].x+k));
// printf("%d\n",ans);
}
printf("%lld",ans);
return 0;
}
题解:
题意为去掉一条边,看此图是否仍为一个二分图;
我们考虑去掉的这条边必定是所有奇环的交,且不能在任何的偶环上,\(tarjan\)找出所有环(这里的所有环是指写出的算法所能找出的环,并非真正意义上的所有环)
每当我们遇到一条返祖边,差分记录环覆盖的边,统计答案时满足前面我们所给的条件即可;
我们发现当我们的搜索顺序不同时,我们所找出的环也不同,但是,这并不影响我们的结果,因为如果一结果对一种图成立,那么他必定对所有图成立;
\(code:\)
#include<cstdio>
#include<algorithm>
#include<ctype.h>
#include<vector>
#include<queue>
#include<cstring>
#include<map>
#include<stdlib.h>
#include<ctime>
#define lowbit(x) (x&-x)
#define ll long long
#define ld double
#define mod 998244353
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
// return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
bool flag=0;
while(!isdigit(tt=gc())&&tt!='-');
tt=='-'?(flag=1,x=0):(x=tt-'0');
while(isdigit(tt=gc())) x=x*10+tt-'0';
if(flag) x=-x;
}
struct node{
int x,id;
inline node(int a=0,int b=0)
{x=a,id=b;}
};
const int maxn=1e5+2;
int n,m,dep[maxn],tot;
int cnt[maxn][2];
//0 1 odd
//0 0 eve
vector<node>G[maxn];
void dfs(int x,int pre)
{
for(int i=G[x].size()-1;i>=0;i--)
{
int p=G[x][i].x,id=G[x][i].id;
if(id==pre) continue;
if(!dep[p])
{
dep[p]=dep[x]+1;dfs(p,id);
cnt[x][0]+=cnt[p][0];
cnt[x][1]+=cnt[p][1];
}
else if(dep[p]<=dep[x])
{
if((dep[x]-dep[p])&1) cnt[x][0]++,cnt[p][0]--;
else cnt[x][1]++,cnt[p][1]--,tot++;
}
}
}
int main()
{
// freopen("voltage.in","r",stdin);
read(n),read(m);
for(int i=1;i<=m;i++)
{
int x,y;
read(x),read(y);
G[x].push_back(node(y,i));
G[y].push_back(node(x,i));
}
int ans=0;
for(int i=1;i<=n;i++) if(!dep[i]) dep[i]=1,dfs(i,0);
for(int i=1;i<=n;i++) if(dep[i]!=1&&!cnt[i][0]&&cnt[i][1]==tot) ans++;
printf("%d",ans+(tot==1));
}