好久没有写了,今天是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;
}