[luogu]10月1日夏令营day1
来源:互联网 发布:怎么学linux 编辑:程序博客网 时间:2024/04/27 18:58
//10月1去了清北,又没上成洛谷
//作为洛谷的忠实粉真不应该
//今天做了做
T1
(想了解这个直接搜题目名即可)
题目描述
我妻蛤乃给你出了一道送命题:
黄梅时节家家雨,青草池塘处处蛙~
有n只青蛙,第i只青蛙会每过xi秒会连续叫yi秒。然而由于青蛙的寿命在增加,所以从第二次开始每次休息结束
后这只青蛙连续叫的时间会增加zi秒。
给定n只青蛙,每一只的xi,yi,zi,以及时间t,求在前t秒中,所有青蛙共叫了多少秒。
输入输出格式
输入格式:
第一行两个数n和t
之后n行,第i+1行每行三个非负整数xi,yi,zi
输出格式:
一行一个数表示答案
输入输出样例
输入样例#1
【子任务】
子任务会给出部分测试数据的特点。 如果你在解决题目中遇到了困难, 可以尝试只解决一部分测试数据。
8 10
9 1 1
1 9 9
4 1 0
2 3 3
1 0 0
1 4 0
9 2 5
1 2 1
输出样例#1:
34
输入样例#2:
1 233333
233 233 233
输出样例#2:
223081
输入样例#3:
10 100000000
1 0 0
1 0 5
1 2 2
1 2 8
1 3 0
1 5 0
1 5 2
1 5 5
1 7 0
1 8 3
输出样例#3:
845787522
每个测试点的数据规模及特点如下表:
测试点编号 n的范围 t的范围 特殊性质
测试点1 n = 1
测试点2 n = 100 t <= 100 x = 0
测试点3 n = 100 y = 0
测试点4 n = 100 z = 0
测试点5 n = 100
测试点6 n = 100000 t <= 100 x = y = z
测试点7 n = 100000 t <= 100 z = 0
测试点8 n = 100000 y = 0
测试点9 n = 100000 t <= 100000
测试点10 n = 100000
对于100%的数据,n <= 100000 , t <= 2000000000,x + y + z > 0
0 <= x , y , z <= 2000000000
【说明】
【样例1说明】
每只青蛙分别叫了1,9,2,6,0,8,1,7秒
【样例2说明】
那只青蛙叫了223081秒
【样例3说明】
每只青蛙分别叫了
0,99993675,99990000,99994999,75000000,83333333,99990002,99993676,87500000,99991837秒
其实看到这道题就能想到用前n项和求
后来想了想爆搜会超时,可以用二分来优化下
注意二分时求前n项和时的边界,可以用 t/(X+Y+Z)来当,要是太大可能会爆long long(我第一次70分就是爆了long long)
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;long long n,t;long long read() { long long x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); } return x * f;}long long x,y,z,sum = 0;bool pd(long long mid) { return (x + y) * mid + ( mid * (mid - 1) ) / 2 * z <= t;}void work() { x = read(), y = read(), z = read(); long long l = 0, r = t / (x + y + z),ans = 0; while(l <= r) { long long mid = (l + r) >> 1; if(pd(mid)) { ans = mid; l = mid + 1; } else r = mid - 1; } long long p = y * ans + ( ans * (ans - 1) ) / 2 * z; sum += p; p = t - p - x * ans - x; if(p > 0) sum += p;}int main() { n = read(), t = read(); for(int i = 1; i <= n; i++) { work(); } cout<<sum<<endl; return 0;}
T2
题目描述
数据结构大师ddd给你出了一道题:
给你一棵树,最开始点权为0,每次将与一个点x树上距离<=1的所有点点权+1,之后询问这些点修改后的点权
和
输入输出格式
输入输出格式
输入格式:
第一行两个数n和m
之后一行n-1个数,第i个数fa[i + 1]表示i + 1点的父亲编号,保证fa[i + 1] < i + 1
之后一行m个数,每个数x依次表示这次操作的点是x
输出格式:
输出一个数,即这m次询问的答案的和
保证答案在有符号64位整数范围内
输入输出样例
说明
样例#3,#4,#5,#6见下发的文件
【子任务】
子任务会给出部分测试数据的特点。
如果你在解决题目中遇到了困难, 可以尝试只解决一部分测试数据。
每个测试点的数据规模及特点如下表:
测试点编号 n的范围 m的范围 特殊性质
测试点1 n = 1000 m = 1000 数据随机
测试点2 n = 1000 m = 1000 数据随机
测试点3 n = 100000 m = 100000
输入样例#1:
6 3
1 1 2 3 3
1 2 3
输出样例#1:
15
输入样例#2:
6 10
1 1 2 3 3
1 4 6 5 2 3 3 3 3 3
输出样例#2:
115
第4页 共7页
测试点编号 n的范围 m的范围 特殊性质
测试点4 n = 100000 m = 100000
测试点5 n = 100000 m = 1000000 树是一条链
测试点6 n = 100000 m = 1000000
测试点7 n = 100000 m = 1000000
测试点8 n = 100000 m = 3000000
测试点9 n = 100000 m = 3000000
测试点10 n = 100000 m = 10000000
//表示赛后看std的方法没看懂
//但我的方法也A了
记录每个点在最后处理完的状态
可以将那个点改变过记录下来,然后dfs一遍
注意题目 保证fa[i + 1] < i + 1 所以只用建单向边就好
然后对于每个点对答案的贡献就是f[i] * (f[i] + 1) / 2
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100000 + 100;int n,m;struct edge { int u,v; int next;}e[maxn << 1];int head[maxn], tot = 0;int read() { int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); } return x * f;}void add(int u, int v) { e[++tot] = (edge){u,v,head[u]}; head[u] = tot;}int val[maxn],f[maxn];void dfs(int x, int fa) { f[x] += val[x] + val[fa]; for(int i = head[x]; i; i = e[i].next) { int v = e[i].v; f[x] += val[v]; dfs(v,x); }}int main() { n = read(), m = read(); for(int i = 2; i <= n; i++) { int v = read(); add(v,i); } for(int i = 1; i <= m; i++) { int a = read(); val[a]++; } dfs(1,0); long long sum = 0; for(int i = 1; i <= n; i++) { sum += (long long)f[i] * (f[i] + 1) / 2; } cout<<sum<<endl; return 0;}
T3
题目描述
江爷爷给你出了一道题:
给你一个图,保证每个点最多属于一个简单环,每个点度数最多为3,求这个图有多少“眼镜图形个数”
保证图联通哦~
其中“眼镜图形个数”,定义为三元组(x,y,S),其中x和y表示图上的两个点,S表示一条x到y的简单路径,而且必
须满足:
1.x和y分别在两个不同的简单环上
2.x所在的简单环与路径S的所有交点仅有x,y所在的简单环与路径S的所有交点仅有y。
(x,y,S)与(y,x,S)算同一个眼镜
如果你无法理解,可以参考样例。
保证图是联通的
输入输出格式
输入格式:
第一行两个数n和m
之后m行,每行两个数x,y表示x和y之间有一条边。
输出格式:
输出一个数,表示眼镜的个数对19260817取膜的结果
输入输出样例
输入样例#1:
说明
样例#3,#4,#5,#6见下发的文件
非常抱歉,出了点小锅,sample5.out好像是空文件,应该是6734568
【子任务】
11 12
1 2
2 3
3 4
4 5
5 1
4 6
6 7
7 8
8 9
9 10
10 11
11 7
输出样例#1:
1
输入样例#2:
14 16
1 2
2 3
3 4
4 1
3 5
5 6
6 7
7 8
8 9
9 6
9 13
13 14
13 10
10 11
11 12
12 10
输出样例#2:
4
子任务会给出部分测试数据的特点。
如果你在解决题目中遇到了困难, 可以尝试只解决一部分测试数据。
测试点编号 n的范围 m的范围 特殊性质
测试点1 n <= 10 m <= 20
测试点2 n <= 20 m <= 40
测试点3 n <= 20 m <= 40
测试点4 n <= 2000 m <= 4000
测试点5 n <= 2000 m <= 4000
测试点6 n <= 1000000 m <= 2000000 简单环个数 <= 2000
测试点7 n <= 1000000 m <= 2000000 简单环个数 <= 2000
测试点8 n <= 1000000 m <= 2000000
测试点9 n <= 1000000 m <= 2000000
测试点10 n <= 1000000 m <= 2000000
//十月1回来后某dalao就让我看这个题,说是树形DP让我推推
首先缩点,注意是无向图不能直接套tarjan
然后就是恶心的树形DP
用f[x]表示以x为根的子树,到x构成的“一半的眼镜”的数量
注意根节点是不是环,如果是环要特殊处理
#include<iostream>#include<cstdio>#include<cstring>#include<vector>using namespace std;#define ll long longconst int maxn = 1000000 + 100;const int mod = 19260817;int n,m;int x[maxn << 1],y[maxn << 1];vector<int>q[maxn];int read() { int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); } return x * f;}//缩点int vis[maxn],f[maxn],belong[maxn],col[maxn],cnt = 0;void dfs(int x) { vis[x] = 1; for(int i = 0; i < q[x].size(); i++) { int v = q[x][i]; if(v == f[x]) continue; if(!vis[v]) f[v] = x, dfs(v); else if(!belong[v]) { int t = x; col[++cnt] = 1; while(1) { belong[t] = cnt; if(t == v) break; t = f[t]; } } }}struct edge { int u,v,next;}e[maxn << 1];int head[maxn],tot = 0;void add(int u, int v) { e[++tot] = (edge){u,v,head[u]}; head[u] = tot;}int fa[maxn],dp[maxn];ll ans = 0;void DP(int x) { for(int i = head[x]; i ; i = e[i].next) { int v = e[i].v; if(v != fa[x]) { fa[v] = x; DP(v); ans = (ans + (ll)dp[v] * dp[x] * (col[x] ? 2 : 1) % mod) % mod; dp[x] = (dp[x] + dp[v]) % mod; } } if(col[x]) { ans = (ans + dp[x]) % mod; dp[x] = (dp[x] * 2 + 1) % mod; }}int main() { n = read(), m = read(); for(int i = 1; i <= m; i++) { x[i] = read(), y[i] = read(); q[x[i]].push_back(y[i]); q[y[i]].push_back(x[i]); } dfs(1); for(int i = 1; i <= n; i++) if(!belong[i]) belong[i] = ++cnt; for(int i = 1; i <= m; i++) { if(belong[x[i]] != belong[y[i]]) { add(belong[x[i]],belong[y[i]]),add(belong[y[i]],belong[x[i]]); } } DP(1); cout<<ans; return 0;}
- [luogu]10月1日夏令营day1
- [luogu]10月1日夏令营day2
- 【SDnoip2014夏令营】【day1】
- 2016.7.7 夏令营 Day1
- 2016长乐夏令营Day1
- 夏令营day1总结
- 【2013年06月26日】趋势科技夏令营面试
- 【2013年06月26日】趋势科技夏令营面试
- 10月1日
- NOIP夏令营day1课程总结
- 【中期报告】2014年CSDN开源夏令营(7月6日~8月2日)中期报告
- 2014年CSDN开源夏令营(7月6日~9月12日)终期报告
- 4月1日-5日小结 及 4月6日-10日规划
- 2007年10月1日(9月29日,9月30日没写)
- 2015年1月6日—10日
- 2005年10月1日
- 2006年1月10日
- 2008年1月10日
- 停课总结(七)
- php—dmeo乘法口决表
- F
- 磁盘故障与恢复
- 停课总结(八)
- [luogu]10月1日夏令营day1
- RuntimeError at /jwt-auth django rest_framework
- Spring Boot学习(一)初始项目,加入web模块,编写简单的RESTful
- 停课总结(九)
- Redis介绍及安装
- SQL语句中聚合函数和Group By一同使用时能取到符合条件的记录中哪些列的信息
- Maven(二)POM文件中的元素
- Activity 切换动画
- 题目汇总