济南刷题冲刺 Day3 下午

77 篇文章 0 订阅
51 篇文章 0 订阅

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; } 
         
       
      
      
     
     
    
    
   
   

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七情六欲·

学生党不容易~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值