P107
zhx
竞赛时间:????年??月??日??:??-??:??
题目名称 | 少女 | 终末 | 旅行 |
名称 | girl | endless | tour |
输入 | girl.in | endless.in | tour.in |
输出 | girl.out | endless.out | tour.out |
每个测试点时限 | 1s | 1s | 1s |
内存限制 | 256MB | 256MB | 256MB |
测试点数目 | 20 | 10 | 10 |
每个测试点分值 | 5 | 10 | 10 |
是否有部分分 | 无 | 无 | 无 |
题目类型 | 传统 | 传统 | 传统 |
注意事项(请务必仔细阅读):
少女
【问题描述】
你是能看到第一题的friends呢。
——hja
少女在图上开车,她们希望把图上每条边分配给与其相连的点中的一个,并且每个点最多被分配一条边,问可能的方案数。
【输入格式】
第一行两个整数 代表点数和边数。
接下来 行每行两个整数代表一条边。
【输出格式】
一行一个整数代表答案对 取模之后的值。
【样例输入】
5 4
1 2
3 2
4 5
4 5
【样例输出】
6
【数据范围与规定】
对于 的数据, 。
对于 的数据, 。
对于 的数据, 。
/*
结论题:边 一条一条的加进去,某个联通块出现大于等于2个环的时候,无解。。
有解的情况只能是有一个环或者没有,,环上的分配方法只有 顺时针、逆时针 分配 两种顺序
所以 章鱼图的外枝(那些树)只能把边分给连向的点,所有 有一个环的图 方案数==2
树的情况:
对于 n 个点的树,只有n-1条边,一定有一个点没有分配到边,把它当做根,所有的边只能向下分配,所以树的情况 答案等于点数
*/
#include
#include
#include
#include
#define Mod 1000000007
#define MAXN 200005
using namespace std;
typedef long long LL;
inline void read(int &x) {
x = 0; register char c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
int fa[MAXN],cnt[MAXN];
int Find(int x){
if( x == fa[x] ) return x;
else return fa[x] = Find(fa[x]);
}
int main(int argc,char *argv[]) {
freopen("gril.in","r",stdin);
freopen("gril.out","w",stdout);
int u,v,fx,fy,n,m; read(n),read(m);
for(int i=1; i<=n<<1; ++i) fa[i] = i,cnt[i] = 1;
while(m--){
read(u),read(v);
if(u == v) u += n;
fx = Find(u),fy = Find(v);
if(fx == fy) cnt[fx] = 2;
else fa[fx] = fy,cnt[fy] += cnt[fx];
}
LL Ans = 1;
for(int i=1; i<=n; ++i)
if(Find(i) == i) Ans = Ans * cnt[i] % Mod;
cout << Ans;
fclose(stdin); fclose(stdout);
}
终末
【问题描述】
你是能看到第二题的friends呢。
——laekov
没有尽头的世界之中,我们想知道 中有多少个数在 进制下和 进制下的表示方式一样。(举个例子, 的 进制表示为 )
【输入格式】
一行两个整数 。
【输出格式】
一行一个整数代表答案。
【样例输入】
21 3
【样例输出】
9
【数据范围与规定】
对于 的数据, 。
对于另外 的数据,
对于 的数据, 。
#include
#include
#include
typedef long long LL;
LL n,ans,cnt;
LL a[1000010];
LL k;
void solve(LL x) {
while(x) {
a[++cnt] = x % k;
x /= k;
}
}
int main(int argc,char**argv) {
freopen("endless.in","r",stdin);
freopen("endless.out","w",stdout);
std::cin >> n >> k;
solve(n);
if(cnt % 2 == 0) ans = pow(k,cnt / 2);
else {
for(int i=cnt; i>=1; i--) {
if(a[i] > 0&&i % 2 == 0) {
ans += pow(k,i / 2);
break;
}
if(a[i] == 0&&i % 2) continue;
ans += a[i] * pow(k,i / 2);
if(i == 1&&a[i] > 0) ans++;
}
}
std::cout << ans;
return 0;
}
旅行
【问题描述】
你是能看到第三题的friends呢。
——aoao
最后的旅行在树上,给你一棵 个点的树,每个点有点权。每次你可以选择一个点开始旅行,获得这个点到 号点路径上所有点的点权,然后把这些点的点权全部变成 。你可以旅行 次,问能获得的最大点权和。
。
【输入格式】
第一行两个整数 。
接下来一行 个整数代表点权。
接下来 行每行两个数代表树上一条边。
【输出格式】
输出一行代表答案。
【样例输入】
5 2
4 3 2 1 1
1 2
1 5
2 3
2 4
【样例输出】
10
【数据规模与约定】
对于 的数据,
对于 的数据, 。
对于 的数据, ,点权是不超过 的正整数。
#include
#include
#include
#include
#include
#define MAXN 100005 using namespace std; typedef long long LL; int head[MAXN],tot,fa[MAXN],leaf,siz[MAXN]; LL val[MAXN]; struct Edge{ int to,next; }e[MAXN << 1]; inline void read(int &x) { x = 0 ; register char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)) x = x * 10 + c - '0' , c = getchar(); } inline void Read(LL &x) { x = 0 ; register char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)) x = x * 10 + c - '0' , c = getchar(); } inline void Add_Edge(int u,int v) { e[++tot].to = v, e[tot].next = head[u],head[u] = tot; e[++tot].to = u, e[tot].next = head[v],head[v] = tot; } void DFS(int u,int ft) { fa[u] = ft,val[u] += val[ft],siz[u] = 1; for(int i=head[u]; i; i=e[i].next){ int v = e[i].to; if(v == ft) continue; DFS(v,u); siz[u] += siz[v]; } if(siz[u] == 1) ++leaf; } void Dfs(int u,LL Vk) { val[u] -= Vk; for(int i=head[u]; i; i=e[i].next) { int v = e[i].to; if(v == fa[u]) continue; Dfs(v,Vk); } } void Modify(int u,int ft){ if(u == 0) return; if(val[u] == 0 && ft != -1) return; for(int i=head[u]; i; i=e[i].next){ int v = e[i].to; if(v == ft || v == fa[u] || val[v] == 0) continue; Dfs(v,val[u]); } val[u] = 0; Modify(fa[u],u); } int main(int argc,char *argv[]) { freopen("tour.in","r",stdin); freopen("tour.out","w",stdout); int n,k; read(n),read(k); LL Sum = 0; for(int i=1; i<=n; ++i) Read(val[i]),Sum += val[i]; for(int u,v,i=1; i
Max) Max = val[i],pos = i; if(Max == 0) break; Ans += val[pos],val[pos] = 0; Modify(pos,-1); } cout << Ans; fclose(stdin); fclose(stdout); return 0; }