wannafly练习赛8
来源:互联网 发布:audition cc 2018 mac 编辑:程序博客网 时间:2024/05/29 08:01
https://www.nowcoder.com/acm/contest/39#question
收获:学习了容斥原理(一语成谶,当亚洲赛开始前我告诉自己,如果现在不努力学习算法,以后肯定还要在学习,但是那个时候学习的时候就有一点悲伤的感觉了qwq),和a,b的脑洞。a是数学脑洞,b是前缀和,也有线段树。(然而不加挂都过不去)
不足:线段树代码明显写的不好,码力还是不行。慢慢提高吧qwq
A :给定n,求1-n中每个数的 约数和的和。
思路:开始蒙蔽,后来发现枚举约数1-n,除一下就行了(商就是n内有多少个)
#include <bits/stdc++.h>using namespace std;/**/int main(){ int m; scanf("%d",&m); int sum=0; for(int i=1;i<=m;i++){ sum+=m/i; } printf("%d\n",sum); return 0;}
B 一个数轴,每一个储物点会有一些东西,同时它们之间存在距离。
每次给个区间[l,r],查询把这个区间内所有储物点的东西运到另外一个储物点的代价是多少?
比如储物点i有x个东西,要运到储物点j,代价为x * dist( i , j )
dist就是储物点间的距离。
思路:用前缀和维护一下,维护距离,数量和 距离*数量的前缀和。
分两种情况。当要移动的位置x在区间左边。 和再区间右边。
(具体可以这样理解,物品从区间移动到最左边,然后再移动到x,当x区间左边时,)
线段树也是这样
#include<bits/stdc++.h>using namespace std;#define LL long long#define MN 200010int n,m,ll,rr,dis[MN],sum1[MN],sum2[MN],a[MN],x,p=1e9+7;int work(int l,int r,int k,int x){ if(l>r) return 0; return k==-1?((sum1[r]-sum1[l-1]+p)%p-((LL)dis[x]*((sum2[r]-sum2[l-1]+p)%p))%p+p)%p :(((LL)dis[x]*((sum2[r]-sum2[l-1]+p)%p))%p-(sum1[r]-sum1[l-1]+p)%p+p)%p;}int main(){// freopen("sample3.in","r",stdin);// freopen("a.txt","w",stdout); cin>>n>>m;for(int i=2,_;i<=n;i++) cin>>_,dis[i]=(dis[i-1]+_)%p;//sum1[i]=(sum1[i-1]+dis[i])%p; for(int i=1;i<=n;i++) cin>>a[i],a[i]%=p,sum2[i]=(sum2[i-1]+a[i])%p,sum1[i]=(sum1[i-1]+((LL)a[i]*dis[i])%p)%p;// for(int i=1;i<=n;i++) if(sum2[i]<0||dis[i]<0||a[i]<0) cout<<" swdwd"; while(m--) { cin>>x>>ll>>rr; if(x>rr) cout<<work(ll,rr,1,x)<<endl; else if(x<ll) cout<<work(ll,rr,-1,x)<<endl; else cout<<(work(ll,x-1,1,x)+work(x+1,rr,-1,x))%p<<endl; } return 0;}
#include<cstdio>#include<cstring>#include<algorithm>#define LL long long intusing namespace std;const int maxn = 200005,P = 1e9+7;inline LL read(){ LL out = 0,flag = 1;char c = getchar(); while (c < 48 || c > 57) {if (c == '-') flag = -1;c = getchar();} while (c >= 48 &&c <= 57) {out = out * 10 + c - 48;c = getchar();} return out * flag;}LL n,m,Sum[maxn],A[maxn];void init(){ n = read(); m = read(); Sum[1] = 0; for (int i = 2; i <= n; i++) Sum[i] = (Sum[i - 1] + read()) % P; for (int i = 1; i <= n; i++) A[i] = read() % P;}LL V[2][4 * maxn],sum[4 * maxn];void build(int u,int l,int r){ if (l == r){ V[0][u] = V[1][u] = 0; sum[u] = A[l]; }else { int mid = (l + r) >> 1; build(u << 1,l,mid); build(u << 1 | 1,mid + 1,r); V[0][u] = (V[0][u<<1] + V[0][u<<1|1] + sum[u<<1|1] * (Sum[mid + 1] - Sum[l]) % P) % P; V[1][u] = (V[1][u<<1] + V[1][u<<1|1] + sum[u<<1] * (Sum[r] - Sum[mid]) % P) % P; sum[u] = (sum[u << 1] + sum[u << 1 | 1]) % P; }}struct node{ LL v,sum,l,r;};int L,R;node Query(int u,int l,int r,int p){ if (l >= L && r <= R){ return (node){V[p][u],sum[u],l,r}; }else { int mid = (l + r) >> 1; if (mid >= R) return Query(u<<1,l,mid,p); else if (mid < L) return Query(u<<1|1,mid + 1,r,p); else { node a = Query(u<<1,l,mid,p),b = Query(u<<1|1,mid + 1,r,p); if (p == 0){ return (node){(a.v + b.v + b.sum * (Sum[mid + 1] - Sum[a.l]) % P) % P,(a.sum + b.sum) % P,a.l,b.r}; }else { return (node){(a.v + b.v + a.sum * (Sum[b.r] - Sum[mid]) % P) % P,(a.sum + b.sum) % P,a.l,b.r}; } } }}void solve(){ LL x,l,r,ans; node u; while (m--){ x = read(); l = read(); r = read(); if (x <= l){ L = l; R = r; u = Query(1,1,n,0); printf("%lld\n",((u.v + u.sum * (Sum[l] - Sum[x]) % P) % P + P) % P); }else if (x >= r){ L = l; R = r; u = Query(1,1,n,1); printf("%lld\n",((u.v + u.sum * (Sum[x] - Sum[r]) % P) % P + P) % P); }else { L = x; R = r; u = Query(1,1,n,0); ans = u.v; L = l; R = x; u = Query(1,1,n,1); ans =((ans + u.v) % P + P) % P; printf("%lld\n",ans); } }}int main(){ init(); build(1,1,n); solve(); return 0;}
D直接写就行,这个比较水qwq,求联通分量之后,-1就行。(特判为1)
include <bits/stdc++.h>using namespace std;/* 水题?分块?*/const int maxn=1e5+200;bool vis[maxn];int m,n;vector<int>g[maxn];void dfs(int u){ for(int i=0;i<g[u].size();i++){ int to=g[u][i]; if(!vis[to]){ vis[to]=true; dfs(to); } }}int main(){ int a,b; scanf("%d%d",&m,&n); memset(vis,false,sizeof(vis)); for(int i=0;i<n;i++){ scanf("%d%d",&a,&b); g[a].push_back(b); g[b].push_back(a); } int sum=0; for(int i=1;i<=m;i++){ if(!vis[i]){ vis[i]=true; dfs(i); sum++; } } printf("%d\n",sum-1); return 0;}
E :容斥。求出n的全排列,其实我感觉这个写法很模板qwq。
#include <bits/stdc++.h>using namespace std;/* 容斥原理。 现在学这种东西,心里是很伤心的, 伤心自己以前没有好好看数学的东西qwq 主要是比赛前太害怕搜索会出事了*/typedef long long ll;const int maxn=25;int va[maxn];int n;ll m;ll solve(int s,ll num){ ll sumall=0; for(int i=0;i<(1<<s);i++){ int tim=0; ll sum=1; for(int j=0;j<s;j++){ if(i&(1<<j)){ sum*=va[j]; tim++; } } if(tim%2){ sumall+=num/sum; } else if(tim!=0){ sumall-=num/sum; } //cout<<sumall<<" "<<num<<" "<<sum<<endl; } return sumall;}int main(){ int a;ll b; while(~scanf("%d%lld",&a,&b)){ for(int i=0;i<a;i++){ scanf("%d",&va[i]); } printf("%d\n",solve(a,b)); } return 0;}
阅读全文
0 0
- wannafly练习赛8
- wannafly 练习8 D加边的无向图
- 10.9wannafly模拟赛
- Wannafly模拟赛4
- Wannafly模拟赛3
- Wannafly 第一次群赛总结
- Wannafly模拟赛3 题解
- Wannafly模拟赛3 题解
- Wannafly模拟赛5 ASplit
- Wannafly模拟赛5 DAria
- Wannafly模拟赛4 题解
- Wannafly模拟赛 树【思维+Dp】
- Wannafly模拟赛 矩阵 二维矩阵hash
- Wannafly模拟赛 树(dp)
- Wannafly模拟赛2 A题
- Wannafly模拟赛 矩阵 [矩阵hash+二分]
- Wannafly模拟赛3 反蝴蝶效应
- Wannafly模拟赛3 生物课程
- markdown编辑器
- 智能语音前行
- CSS样式(元素包含规范、规避脱标流、浮动盒子居中显示、图片和文字垂直居中对齐)
- 伙伴系统的概述
- (三十九)MaterialDesign 动画
- wannafly练习赛8
- Java设计模式之适配器模式(Adapter Pattern)
- 最近有点累 QUCT
- 手机发送验证码的业务逻辑探究-主要是安全性,响应性
- 20ABerOS file system
- 随笔
- Convolution Neural Network (CNN) 原理与实现
- 59. DNS 服务器
- Python之继承与多态