CF#R582(div 3)总结
先吐槽一下学校,为什么要在8.31开学啊,打了一半心态崩了
就退了,想着应该不会掉很多的.....................................
气死了,补一下题解吧(题解是后来补的,花了差不多俩小时)
很容易想到,这个东西可以直接统计每个数字是奇数还是偶数的出现次数,取较小值即可
#include<bits/stdc++.h> using namespace std; #define LL long long int a,n,m,p,q; int ans; int main() { cin>>n; for (int i=1;i<=n;i++) { int x;cin>>x; if (x&1) p++; else q++; } printf("%d\n",min(p,q)); return 0; }
B. Bad Prices
本来想的是用树状数组直接维护一下,但是懒得写离散化,手玩数据发现,当前点只需要看后面有没有数比它小即可,倒着扫描即可
#include<bits/stdc++.h> #define lowbit(x) (x&(-x)) using namespace std; const int N=2e5+7; int tree[N]; int T; int ans,m,n; int a[N],p[N]; int main() { cin>>T; while (T--) { cin>>n;ans=0; for (int i=1;i<=n;i++) cin>>a[i];int mn=a[n]; for (int i=n-1;i>=1;i--) { if (a[i]>mn) {ans++;} else {mn=min(mn,a[i]);continue;} } printf("%d\n",ans); } return 0; }
C. Book Reading
对于每个数字肯定有一定的循环节,我们先处理出他需要的循环次数,对于循环节直接暴力计算即可
写的时候犯傻了,懒得找规律,就直接全算了一遍,好像可以分质数非质数分类的(雾
#include<bits/stdc++.h> using namespace std; #define LL long long LL ans; LL m,n,T; int main() { cin>>T; while (T--) { cin>>n>>m; LL p=m%10;ans=p;LL tm=n/m; if (p==1) { ans=(tm/10)*45; for (int i=1;i<=tm%10;i++) ans+=i; } if (p==2) { ans=(tm/5)*20; for (int i=1;i<=tm%5;i++) ans+=i*2; } if (p==3) { ans=(tm/10)*(45);LL k=3; for (int i=1;i<=tm%10;i++) { ans+=k; k=(k+3)%10; } } if (p==4) { ans=(tm/5)*(20);LL k=4; for (int i=1;i<=tm%5;i++) { ans+=k; k=(k+4)%10; } } if (p==5) { ans=(tm/2)*(5);LL k=5; for (int i=1;i<=tm%2;i++) { ans+=k; k=(k+5)%10; } } if (p==6) { ans=(tm/5)*(20);LL k=6; for (int i=1;i<=tm%5;i++) { ans+=k; k=(k+6)%10; } } if (p==7) { ans=(tm/10)*(45);LL k=7; for (int i=1;i<=tm%10;i++) { ans+=k; k=(k+7)%10; } } if (p==8) { ans=(tm/5)*(20);LL k=8; for (int i=1;i<=tm%5;i++) { ans+=k; k=(k+8)%10; } } if (p==9) { ans=(tm/10)*(45);LL k=9; for (int i=1;i<=tm%10;i++) { ans+=k; k=(k+9)%10; } } cout<<ans<<endl; } return 0; }
D2. Equalizing by Division
这题有毒,本来考场上直接可以写开的,我非要用堆维护,我是zz,所以就一直调不出来,气死人了
其实我们对于每个值,直接将其分解,布数计入到一个数组即可,最后扫描一遍去最小值即可
#include<bits/stdc++.h> #define I inline using namespace std; const int N=2e5+7; const int INF=0x7f7f7f7f; vector<int> v[N]; int n,k,a[N],st; I 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*10+ch-'0';ch=getchar();} return x*f; } void solve(int x) { int cnt=0; while (x) { v[x].push_back(cnt); x>>=1; cnt++; } } int main() { n=read(),k=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=n;i++) solve(a[i]),st=max(st,a[i]); int ans=INF; for (int i=0;i<=st;i++) { if (v[i].size()<k) continue; sort(v[i].begin(),v[i].end()); ans=min(ans,accumulate(v[i].begin(),v[i].begin()+k,0)); } cout<<ans; return 0; }
E. Two Small Strings
不清楚题解什么意思,自己YY了个算法:
我们考虑三个字符排列的每种情况,只有6种,先对其进行判断看看可以不可以自己首位相连
如果不行,那么判断自己本身涵盖题目所给字符,直接暴力输出自己每个字符N遍即可
#include<bits/stdc++.h> using namespace std; string s[7],sp; int n,Q; bool vis[7]; int main() { s[1]="abc",s[2]="acb",s[3]="bca",s[4]="bac",s[5]="cab",s[6]="cba"; cin>>n; string ss[3]; int pos=0; cin>>ss[1]>>ss[2]; for (int i=1;i<=6;i++) { if (s[i].find(ss[1])!=-1) vis[i]=true; if (s[i].find(ss[2])!=-1) vis[i]=true; if (!vis[i]) Q=i; } if (n==1) {cout<<"YES"<<endl<<s[Q];return 0;} pos=0; for (int i=1;i<=6;i++) { if (vis[i]) continue; sp.clear();sp+=s[i][2],sp+=s[i][0]; if (sp.find(ss[1])!=-1) continue; if (sp.find(ss[2])!=-1) continue; pos=i; } if (pos) { printf("YES\n"); for (int i=1;i<=n;i++) cout<<s[pos]; } else { printf("YES\n"); for (int i=1;i<=n;i++) cout<<s[Q][0]; for (int i=1;i<=n;i++) cout<<s[Q][1]; for (int i=1;i<=n;i++) cout<<s[Q][2]; } return 0; }
F. Unstable String Sort
咕咕咕,不会写,题解也看不懂,awcsl。。。。。。
G. Path Queries
好久没写树上启发式合并了,一眼题吧,应该算是
首先对每个m个限制进行考虑,将其按需要的限制排序,之后对于每个边并查集维护
启发式合并掉,答案直接统计即可,最后离散回来,输出即可
#include<bits/stdc++.h> #define I inline #define LL long long using namespace std; const int N=2e5+7; LL res; int sz[N],n,fa[N],m; LL calc(LL x) { return 1LL*(x)*(x-1)/2LL; } I 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*10+ch-'0';ch=getchar();} return x*f; } int find(int x) { if (fa[x]!=x) return fa[x]=find(fa[x]); return fa[x]; } struct node { LL pos,ans,id; } t[N]; struct edge { int from,to,dis; bool operator <(const edge &x) const { return dis<x.dis; } } e[N]; bool cmp1(node a,node b) { return a.pos<b.pos; } bool cmp2(node a,node b) { return a.id<b.id; } void merge(int x,int y) { int fx=find(x),fy=find(y); if (sz[fx]>sz[fy]) swap(fx,fy); res-=calc(sz[fx]);res-=calc(sz[fy]); sz[fy]+=sz[fx]; res+=calc(sz[fy]); fa[fx]=fy; } void solve() { int pos=1; for (int i=1;i<=m;i++) { while (e[pos].dis<=t[i].pos&&pos<=n-1) { merge(e[pos].from,e[pos].to); pos++; } t[i].ans=res; } } int main() { n=read();m=read(); for (int i=1;i<n;i++) { int x=read(),y=read(),z=read(); e[i].from=x;e[i].to=y;e[i].dis=z; } for (int i=1;i<=m;i++) { t[i].pos=read(),t[i].id=i; } sort(e+1,e+n);sort(t+1,t+m+1,cmp1); for (int i=1;i<=n;i++) fa[i]=i,sz[i]=1; solve(); sort(t+1,t+m+1,cmp2); for (int i=1;i<=m;i++) printf("%I64d ",t[i].ans); return 0; }
代码纯属原创,如果跟题解思路相同或者代码相同,如本人无瓜,qwq
谁能教教我F怎么写的啊,我太菜了。