2020牛客国庆集训派对day3
A Leftbest
给出一个数列,问对于ai前面的比他大的最小值的和。
用set upperbound一下就好了
int main(){int n;scanf("%d",&n);long long ans = 0;set<int> fk;for(int i = 0; i < n; ++i){int x;scanf("%d",&x);auto it = fk.upper_bound(x);fk.insert(x);if(it==fk.end())continue;ans+=*it;}printf("%lld\n",ans);
}
B First Date
给出一个n个节点m条边的图,每条边都有一个x,y值,他的权值就是x+y*a。这个a是一个[0,1]平均分布。问从s到t的期望时间的最小值。
(这个题很神奇,a是平均分布,为什么a就不能直接等于1/2?)
迭代a从0到1的值,然后计算每一个a,s到t的最小时间。最后除以迭代次数得出平均值。
struct Edge{int v;int x,y;
};vector<Edge> g[1000];
double dis[10000];void bfs(int u,double a){queue<int> q;q.push(u);dis[u] = 0;while(!q.empty()){int t = q.front();q.pop();for(auto it : g[t]){int v = it.v;double w = it.x + a*it.y;if(dis[v]==-1 || dis[v] > dis[t]+w){dis[v] = dis[t]+w;q.push(v);}}}
}
int main(){int n,m,s,t;cin>>n>>m>>s>>t;for(int i = 0; i <m; ++i){int u,v,x,y;cin>>u>>v>>x>>y;g[u].pb({v,x,y});g[v].pb({u,x,y});}double ans = 0;for(double a = 0; a <=1; a+=0.00001) {for(int i = 1; i <=n; ++i)dis[i]=-1;bfs(s,a);ans += dis[t];}printf("%.5lf\n",ans/100000);
}
C Sequence
要补吗???
D Capture Stars
给出两个内切圆,圆心在x轴且必过(0,0)。且给出m个点(x,y), 问另外一个夹在这两个圆之间的圆能最多包含对少个点(x,y)。
圆的反演(新知识啊)。圆的反演一般用在圆的外切内切的题。
反演定义:如果一个圆的圆心为0,圆心为r, 从圆心o拉出一条射线,对于圆上一点P,圆外一点, 如果 , 则这两个点互为反演。
因此该圆就可以变成一条直线了。
由于题目的两个圆过(0,0),而我们需要找一个共用的反演圆将这两个圆上的点都使用同一个反演圆反演到另外一个平面上。
反演圆圆心(0,0),半径为大圆直径2R。
由于圆的反演肯定是对于经过反演中心(0,0)和圆心的直线的垂线,因此对于大圆上一点,反演点,
对于小圆上一点,反演点,
对于平面上任意一点,反演点, 有
同理
那么问题变成了有两条直线和,一些点(x',y'),问有一个圆在两直线间,最多包含多少个点(x',y')
圆的中心肯定在两直线中间 ,圆的半径是
圆这条轨道上移动,求移动到某一个点时,覆盖的点最多。
求出每一个点的圆的覆盖范围 , 范围为
最后用加加减减求线段最多覆盖次数就可以了。
double sqr(double x) {return x*x;
}int main(){int t;cin>>t;while(t--){int n;double R,r;scanf("%d%lf%lf",&n,&R,&r);double x0 = R*R/r+R;double r0 = R*R/r-R;vector< pair<double,int> > pos;for(int i = 0; i < n; ++i){double x,y;cin>>x>>y;double l = sqr(x)+sqr(y);x = 4*R*R * x/l;y = 4*R*R * y/l;if(fabs(x-x0)<=r0){double h = sqrt(sqr(r0) - sqr(x-x0));pos.pb(mp(y-h,-1));pos.pb(mp(y+h,1));}}sort(pos.begin(), pos.end());int ct = 0, ans = 0;for(auto it :pos){ct -= it.second;ans = max(ans, ct);}printf("%d\n",ans);}
}
E Triangulation
多边形三角剖分
由于题目是顺时针或者逆时针给出点,因此先全部统一为逆时针的点。
然后区间dp,对于dp[i][k],表示i连一条线到k,把i到k之间的点做一个三角剖分。
找一个在i,k之间的点j,由于是逆时针,因此j必须在i,k的右手边(p[i,k]*p[i,j]<0)。则有dp[i][k] += dp[i][j]*dp[j][k].
struct Point{long long x,y;void read(){sf("%lld%lld",&x,&y);}Point operator -(const Point a){Point ret;ret.x = x-a.x;ret.y = y-a.y;return ret;}long long operator *(const Point a){return x*a.y-y*a.x;}
}p[300];long long dp[300][300];int main(){int n;cin>>n;clr(dp);long long s = 0;fr(i,0,n){p[i].read();if(i)s += (p[i]-p[0])*(p[i-1]-p[0]);}if(s>0){for(int i = 0; i+i<n-1;++i)swap(p[i],p[n-i-1]);}fr(i,0,n){dp[i][(i+1)%n]=1;}for(int l = 2; l<=n;++l)for(int i = 0; i<n;++i){int k = (i+l)%n;for(int j = (i+1)%n;j!=k;j=(j+1)%n){if((p[k]-p[i])*(p[j]-p[i])<0){dp[i][k] = (dp[i][k] + dp[i][j]*dp[j][k])%mod;}}}printf("%lld\n",dp[0][n-1]);
}
F Points
签到题??
统计度数为1的点
int d[1000010];
int main(){int n;scanf("%d",&n);for(int i = 0;i <n-1;++i){int u,v;scanf("%d%d",&u,&v);d[u]++;d[v]++;}int ans = 0;for(int i = 1; i <=n;++i)if(d[i]==1)++ans;printf("%d\n",ans);
}
G ParallelNetworkAnalysis
要补吗??
H Graph
给出n个节点和几种操作(对某两个点连或删边,对某两个加进查询集或者从查询集删除)。
对于询问操作,问查询集中的每两个点是否在树上连通。
对于树上的增删边直接用LCT维护。
对于查询集是否连通,每加入两个点,则分配给该点一个比较大的随机值。如果查询集的点都连通,那么查询集的总异或值为0。 (为什么随机?我觉得是因为查询集的点数其实很少的,随机出一个很大的数才能防止不同的值异或后也为0,譬如1,2,3)
问题变成了LCT怎么维护整个树的异或值。在加入点到查询值的时候,直接修改树上节点的值。但是由于LCT维护的splay是一条链来的,pushup的时候不会统计非链的节点,因此需要多一个sum来统计。这个sum在link的时候被加进去。这样在splay做pushup的时候就可以一直往上滚了。
(不能直接把这个值加入到节点的值中,因为当access变成一条链的时候父节点和当前节点就拥有重复的值了)
access的时候,由于非链的节点变成链,需要对sum做修改(减去以前的,添加现在的)。
link的时候,也需要先对x,y做一个换根,保证连接的时候是根。
int son[N][2], f[N];
int sum[N],sum1[N],r[N];
int a[N];
int n,m;
int cnt;void pushup(int x){sum[x] = sum[son[x][0]] ^ sum[son[x][1]] ^ a[x] ^ sum1[x];
}void switch_son(int x){int t = son[x][0]; son[x][0] = son[x][1];son[x][1] = t;r[x]^=1;
}void pushdown(int x){if(r[x]){if(son[x][0])switch_son(son[x][0]);if(son[x][1])switch_son(son[x][1]);r[x] = 0;}
}bool isroot(int x){return !(son[f[x]][0]==x || son[f[x]][1]==x);
}void rotate(int x){int y = f[x], z = f[y];if(!isroot(y)){son[z][son[z][1]==y] = x;}int p = son[y][1]==x;int t = son[x][!p];son[x][!p] = y;son[y][p] = t;f[x] = z; f[y] = x; if(t)f[t] = y;pushup(y);
}void splay (int x) {//push down firstint y = x;stack<int> st;st.push(y);while(!isroot(y)) st.push(f[y]),y=f[y];while(!st.empty()) {pushdown(st.top()),st.pop();}while(!isroot(x)){int y = f[x];int z = f[y];if(!isroot(y)){rotate(y);}rotate(x);}pushup(x);
}void access(int x){int y = 0;while(x){splay(x);sum1[x] ^=sum[son[x][1]];sum1[x] ^=sum[y];son[x][1] = y; y = x;pushup(x);x = f[x];}
}void make_root(int x){access(x);splay(x);switch_son(x);
}int findroot (int x) {access(x);splay(x);while(son[x][0])x = son[x][0];return x;
}void link(int x, int y){make_root(x);if(findroot(y)==x)return;if(sum[x]){cnt--;}if(sum[y]){cnt--;}make_root(y);f[y] = x;sum1[x]^=sum[y];make_root(x);pushup(x);if(sum[x]){cnt++;}
}void cut(int x, int y){make_root(x);access(y);
// if(findroot(y)!=x) return;splay(x);if(f[y] != x || son[y][0]) return; //very trickyif(sum[x]){cnt--;}f[y] = 0;son[x][1] =0;splay(x);if(sum[x]){cnt++;}splay(y);if(sum[y]){cnt++;}
}void add(int x, int v){make_root(x);if(sum[x]){cnt--;}a[x]^=v;pushup(x);if(sum[x]){cnt++;}
}void add(int x, int y, int v){add(x,v);add(y,v);
}int main(){srand(time(0));int t;cin>>t;while(t--){sf("%d%d",&n,&m);fr(i,0,n+1){a[i] = 0;clr(son[i]);f[i] = 0;sum[i] = 0;r[i] = 0;sum1[i] = 0;}cnt = 0;map<pair<int,int>,int > v;fr(i,0,m){int op,x,y;sf("%d",&op);if(op!=5){sf("%d %d",&x,&y);if(x>y)swap(x,y);}if(op==1){link(x,y);}else if(op==2){cut(x,y);}else if(op==3){v[mp(x,y)] = rand();add(x,y,v[mp(x,y)]);}else if(op==4){add(x,y,v[mp(x,y)]);v[mp(x,y)] = 0;}else if(op==5){if(cnt==0)printf("YES\n");else printf("NO\n");}}}
}
I Rooted Tree
我也不知道为什么,该序列是一个哈代-拉马努金拆分数列
把数列分解成奇数项和偶数项去dp求通项
然后就可以直接dp了
long long f[500010], g[500010];
long long dp[500010];
int mod = 998244353;int main(){int n;scanf("%d",&n);for(long long i = 1; i<=n;++i){f[i] = (3ll*i*i-i)/2;g[i] = (3ll*i*i+i)/2;}dp[0] = 1;for(int i = 1; i<=n;i++){for(int j = 1; f[j]<=i;j++){if(j%2==1){dp[i] += dp[i-f[j]];if(g[j]<=i)dp[i]+= dp[i-g[j]];}else {dp[i] -= dp[i-f[j]];if(g[j]<=i)dp[i]-=dp[i-g[j]];}}dp[i] %= mod;if (dp[i] < 0) dp[i] += mod;//printf("i = %d dp = %lld\n",i,dp[i]);}printf("%lld\n",dp[n-1]);
}
J Flowers
给出n种花,每种花有ai朵。问能凑成多少束花,每束花由m种不同的花组成。
二分枚举答案,对于需要组成k束花,则需要k*m朵。扫描每一种花判断可以最多给多少朵。
int a[300010];
int n,m;int main(){int t;cin>>t;while(t--){cin>>n>>m;long long sum = 0;for(int i = 0; i < n; ++i){scanf("%d",&a[i]);sum += a[i];}auto check = [&](long long num){long long tot = 0;for(int i = 0; i< n; ++i){tot += min((long long)a[i],num);}return tot>=num*m;};long long l = 0, r = sum/m+1;long long ans = 0;while(l+1<r){ll mid = (l+r)>>1;if(check(mid)){l = mid;}else r = mid;}cout<<l<<endl;}
}
2020牛客国庆集训派对day3相关推荐
- 2020牛客国庆集训派对day3 I.Rooted Tree(哈代-拉马努金拆分数列)
2020牛客国庆集训派对day3 I.Rooted Tree(哈代-拉马努金拆分数列) 题目 https://ac.nowcoder.com/acm/contest/7830/I 题意 给你n个点,问 ...
- 2020牛客国庆集训派对day3 Leftbest
Leftbest 链接:https://ac.nowcoder.com/acm/contest/7830/A 来源:牛客网 题目描述 Jack is worried about being singl ...
- 2020牛客国庆集训派对day3 Points
Points 题目描述 Jack and Rose are playing games after working out so many difficult problems. They toget ...
- 2020牛客国庆集训派对day2 补题J
2020牛客国庆集训派对day2 补题J:VIRUS OUTBREAK 题目描述 The State Veterinary Services Department recently reported ...
- 2020牛客国庆集训派对day2 H-STROOP EFFECT(英语题)
2020牛客国庆集训派对day2 H-STROOP EFFECT(英语题) 题目 https://ac.nowcoder.com/acm/contest/7818/H 题意 这题目真的太难读懂了,赛后 ...
- 2020牛客国庆集训派对day8 G-Shuffle Cards(扩展STL容器,rope可持久化平衡树)
2020牛客国庆集训派对day8 G-Shuffle Cards(扩展STL容器,rope可持久化平衡树) 题目 https://ac.nowcoder.com/acm/contest/7865/G ...
- 2020牛客国庆集训派对day1 A.ABB
2020牛客国庆集训派对day1 A.ABB 题目链接 题目描述 Fernando was hired by the University of Waterloo to finish a develo ...
- 2020牛客国庆集训派对day2 F题 Java大数处理
题目: 链接:https://ac.nowcoder.com/acm/contest/16913/F 来源:牛客网 The following code snippet calculates the ...
- 2020牛客国庆集训派对day8
牛客网链接 文章目录 Easy Chess 题意: 题解: Easy Problemset 题意 题解: Shuffle Cards 题解: Diff-prime Pairs 题意 题解: 代码: E ...
- 2020牛客国庆集训派对day4 Arithmetic Progressions
Arithmetic Progressions 链接:https://ac.nowcoder.com/acm/contest/7831/B 来源:牛客网 题目描述 An arithmetic prog ...
最新文章
- MySQL外键约束On Delete、On Update各取值的含义
- android ndk 界面开发教程,Android NDK开发之入门教程
- 【深度学习】神经网络知识专题总结
- 视觉基础与开发思路-第九节形态学操作
- 聊聊AspectCore动态代理中的拦截器(一)
- c语言100000阶乘,求10000的阶乘(c语言代码实现)
- 【算法分析与设计】经典排序算法实现
- 零基础入门Python数据分析,只需要看懂这一张图,附下载链接!
- 布谷鸟沙盒分析静态文件_【虚拟机镜像分析】
- JavaScript------字符串与HTML格式相互转换
- java中String的七种用法
- js 实现 间隙滚动效果
- python随机森林回归数据实战
- 由于ORACLE_SID未设定造成的ora-12162 错误
- 【b站黑马程序员C++视频学习笔记-继承方式】
- gamemaker学习笔记:打包Android过程记录
- 计算机上的波特率标准,电子信号术语-波特率9600计算单位是波特/每秒(B/s)
- python thinker_Thinker
- 安卓软件开发你知道需要学什么吗,看这里?
- 查看,设置,设备的 竖屏-横屏模式 screen.orientation