ABC
签到,过水已隐藏
D
做完第一次操作后数字只有2e5,位数很小,可以直接模拟了
#include<bits/stdc++.h> using namespace std; const int N=2e5+7; int n,n1,s1,s2,a[N],pw1[N],pw2[N]; char ch[N]; int solve(int x) { if(!x)return 0; int num=0,tmp=x; while(x){if(x&1)num++;x/=2;} return 1+solve(tmp%num); } int main() { scanf("%d",&n); scanf("%s",ch+1); for(int i=1;i<=n;i++){a[i]=ch[i]-'0';if(a[i])n1++;} if(n1>=2) { pw1[n]=1; for(int i=n-1;i;i--)pw1[i]=2ll*pw1[i+1]%(n1-1); for(int i=1;i<=n;i++)if(a[i])s1=(s1+pw1[i])%(n1-1); } pw2[n]=1; for(int i=n-1;i;i--)pw2[i]=2ll*pw2[i+1]%(n1+1); for(int i=1;i<=n;i++)if(a[i])s2=(s2+pw2[i])%(n1+1); for(int i=1,x;i<=n;i++) if(a[i]) { if(n1<=1)puts("0"); else x=(s1-pw1[i]+n1-1)%(n1-1),printf("%d ",solve(x)+1); } else x=(s2+pw2[i])%(n1+1),printf("%d ",solve(x)+1); }
E
考场上想到贪心,但还是没写出,码力退化严重。
实际上是这样的,把骆驼分两类,然后按照k排序,循环后,若队列大小小于k,则直接加,反之比较与堆顶的价值,注意开小根堆,答案long long
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+7; struct node{int v,k;}a[N],b[N]; int n,na,nb; ll ans; bool operator<(node a,node b){return a.k<b.k;} priority_queue<int,vector<int>,greater<int> >q; int main() { int T;scanf("%d",&T); while(T--) { scanf("%d",&n); ans=0,na=0,nb=0; for(int i=1;i<=n;i++) { int k,l,r;scanf("%d%d%d",&k,&l,&r); if(l>r)ans+=r,a[++na]=(node){l-r,k}; else ans+=l,b[++nb]=(node){r-l,n-k}; } sort(a+1,a+na+1),sort(b+1,b+nb+1); for(int i=1;i<=na;i++) if(a[i].k) { if(q.size()<a[i].k)q.push(a[i].v); else if(q.size()==a[i].k&&a[i].v>q.top())q.pop(),q.push(a[i].v); } while(!q.empty())ans+=q.top(),q.pop(); for(int i=1;i<=nb;i++) if(b[i].k) { if(q.size()<b[i].k)q.push(b[i].v); else if(q.size()==b[i].k&&b[i].v>q.top())q.pop(),q.push(b[i].v); } while(!q.empty())ans+=q.top(),q.pop(); printf("%lld ",ans); } }
F
太难了不写了
rank329 rating=811(新号)