好久没有写了,今天是10.8国庆爽完回来了(来不及伤心了),把之前没弄好的东西都补补


A.小红的字符移动

先写第二个,然后顺序输出即可 简单题,直接上代码

void solve()
{
   string s;
   cin>>s;
   cout<<s[1];
   for(int i=0;i<s.length();i++){
     if(i!=1) cout<<s[i];
   }
}

B 小红的数轴移动

直接模拟,因为方向都是确定的,当x为0之时特判一下就好了,记得开longlong ~~~

using LL = long long;
void solve()
{
   LL n,x;
   cin>>n>>x;
   vector<int>a(n+1,0);
   for(int i=1;i<=n;i++) cin>>a[i];
    LL sum = 0;
    for(int i=1;i<=n;i++){
        if(x==0){
            break;
        }
        else if(x>0){
            x-=a[i];
            sum+=abs(a[i]);
        }
        else{
            x+=a[i];
            sum+=abs(a[i]);
        }
    }
    cout<<sum;
}

C 小红的圆移动

一开始还想麻烦了,对r进行排序来比大小,搞了半天,最后发现,只要在最开始的时候把所有距离算出来,刨包括原点的,然后排序计算即可。

略史。。。。

using LL = long long;
const int N = 1e5+10;
const double pi = 3.14159265358979324;
struct node{
    double x,y,r;
}s[N];

void solve()
{
   int n,k;
   cin>>n>>k;
   for(int i=1;i<=n;i++){
        cin>>s[i].x>>s[i].y>>s[i].r;
   }
   vector<double> q;
   double sum = 0.0;
   int cnt = 0;
   for(int i=1;i<=n;i++){
        double c = pi*s[i].r*s[i].r;
        double op = s[i].r - sqrt(s[i].x*s[i].x + s[i].y*s[i].y);
        if(op<0){
            cnt++;//op小于0表示这个圆肯定不会包括原点,记录一下
        }else q.push_back(c*op);
   }
   sort(q.begin(),q.end());//排序
   int ans = 0;
   for(int i=0;i<q.size();i++){
        sum+=q[i];
        ans++;
        if(n -ans - cnt<=k){
            printf("%.10lf",sum);
            return;
        }
   }
}

D 小红的树上移动

算是一道 基础的综合题,也确实被难住了,因为树和计算分数都不怎么熟练,赛场上直接爆了。。。

赛后重写了一遍,计算每个叶子节点的深度和每个节点的分叉概率,用f数组保存,相乘相加计算即可

对于分数的计算 根据费马小定理 可得 (b/a)%p = b*(pow(a,p-2))%p ,这里b始终为1

using LL =long long;
const int mod = 1e9+7;
vector<LL> g[202020];
LL f[202020];
LL sum = 0;
LL kfc(LL x,LL y)
{
    LL ans=1;
    while(y)
    {
        if(y&1) ans=ans*x%mod;
        y>>=1;
        x=x*x%mod;
    }
    return ans;
}
void dfs(int p,int fa,int dep){
    bool leaf = true;
    for(int i=0;i<g[p].size();i++){
        int son = g[p][i];
        if(son==fa) continue;
        leaf = false;
        f[son] = f[p]*kfc(g[p].size()-(p!=1),mod-2 )%mod;
        dfs(son,p,dep+1);
    }
    if(leaf){
        sum  = (sum + (dep*f[p])%mod)%mod;
    }
}
void solve(){
    int n;
    cin>>n;
    f[1]= 1;
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1,0,1);
    cout<<sum%mod<<endl;
}

E 小红的中位数查询

板子题,不知道主席树(悲!!!)

补个模板

#include <bits/stdc++.h>
using namespace std;
using LL =long long;
#define N 200005
#define lc(x) tr[x].l
#define rc(x) tr[x].r
struct node{
  int l,r,s; //s:节点值域中有多少个数
}tr[N*20];
int root[N],idx;
int n,m,a[N];
vector<int> b;

void build(int &x,int l,int r){
  x=++idx;
  if(l==r) return;
  int m=l+r>>1;
  build(lc(x),l,m);
  build(rc(x),m+1,r);
}
void insert(int x,int &y,int l,int r,int k){
  y=++idx; tr[y]=tr[x]; tr[y].s++;
  if(l==r) return;
  int m=l+r>>1;
  if(k<=m) insert(lc(x),lc(y),l,m,k);
  else insert(rc(x),rc(y),m+1,r,k);
}
int query(int x,int y,int l,int r,int k){
  if(l==r) return l;
  int m=l+r>>1;
  int s=tr[lc(y)].s-tr[lc(x)].s;
  if(k<=s) return query(lc(x),lc(y),l,m,k);
  else return query(rc(x),rc(y),m+1,r,k-s);
}
int main(){
  cin>>n>>m;
  for(int i=1; i<=n; i++){
    cin>>a[i]; 
    b.push_back(a[i]);
  }
  sort(b.begin(),b.end());
  b.erase(unique(b.begin(),b.end()),b.end());
  int bn=b.size();

  build(root[0],1,bn);
  for(int i=1; i<=n; i++){
    int id=lower_bound(b.begin(),b.end(),a[i])-b.begin()+1;
    insert(root[i-1],root[i],1,bn,id);
  }

  while(m--){
    int l,r,k; 
    cin>>l>>r;
    k = (r-l)/2+1;
    int id=query(root[l-1],root[r],1,bn,k)-1;
    cout<<b[id]<<endl;
  }
  return 0;
}