7月22日2022多校冲刺NOIP联训测试4
A.甲国的军队
非常水的一道题,只需要把询问按照差值sort一遍,运用贪心思想累加答案即可.
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define maxn 5000001
#define rll rg ll
using namespace std;
struct node
{
ll a,b,c;
inline friend bool operator<(node a,node b)
{
if(a.c==b.c) return a.b>b.b;
return a.c>b.c;
}
}a[maxn];
ll t,n,now;
ll sum[maxn],ans;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>t;
while(t--)
{
cin>>n;
for(rll i=1;i<=n;i++) cin>>a[i].a>>a[i].b,a[i].c=a[i].b-a[i].a;
sort(a+1,a+n+1);
ans=a[1].b;now=a[1].b-a[1].a;
for(rll i=2;i<=n;i++)
{
if(now<a[i].b) ans+=a[i].b-now,now=a[i].b-a[i].a;
else now-=a[i].a;
}
cout<<ans<<endl;
}
return 0;
}
B.虚弱
累一个前缀,维护一个凸包,再维护两个单调栈找到正与反的最小斜率.
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define maxn 200001
#define rll rg ll
using namespace std;
ll n,cnt;
double a[maxn],sum,qz[maxn],mx,mn,mxa,mna;
double l,r,mid,z,y;
inline double slope(ll x,ll y)
{
return (qz[x]-qz[y])/(double)(x-y);
}
ll s1[maxn],top1,s2[maxn],top2;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
mx=1e10;
cin>>n;
if(n==1)
{
cout<<"0.000000";
return 0;
}
for(rll i=1;i<=n;i++)
cin>>a[i],qz[i]=qz[i-1]+a[i];
for(rll i=0;i<=n;i++)
{
while(top1>=2&&slope(s1[top1-1],s1[top1])>=slope(s1[top1-1],i)) top1--;
s1[++top1]=i;
}
for(rll i=n;i+1;i--)
{
while(top2>=2&&slope(s2[top2-1],s2[top2])>=slope(s2[top2-1],i)) top2--;
s2[++top2]=i;
}
rll x=1,y=1;
rg double t;
while(x<top1||y<top2)
{
if(x!=top1&&(y==top2||slope(s1[x],s1[x+1])<slope(s2[y],s2[y+1])))
t=slope(s1[x],s1[x+1]),x++;
else t=slope(s2[y],s2[y+1]),y++;
mx=min(mx,abs(qz[s1[x]]-(double)s1[x]*t-(qz[s2[y]]-(double)s2[y]*t)));
}
cout<<fixed<<setprecision(6)<<mx;
return 0;
}
C.萨鲁曼的半兽人
具体实现方法:
使用Manacher(一种快速匹配回文串的算法)或暴力找到所有回文串,然后运用贪心思想每次找最大的子串统计即可.
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define maxn 5000001
#define rll rg ll
using namespace std;
struct node
{
ll l,r;
inline friend bool operator<(node a,node b)
{
if(a.l==b.l) return a.r<b.r;
return a.l<b.l;
}
}a[maxn];
char s[maxn],tmp[maxn];
ll n,len;
ll ans;
inline void ins()
{
len=-1;
tmp[++len]='/';
for(rll i=1;i<=n;i++)
{
tmp[++len]='#';
tmp[++len]=s[i];
}
tmp[++len]='#';
tmp[++len]='\';
n=len-1;
}
ll pal[maxn];
inline void manacher()
{
rll mx=0,id;
for(rll i=1;i<=n;i++)
{
if(mx>=i) pal[i]=min(mx-i+1,pal[(id<<1)-i]);
else pal[i]=1;
while(tmp[i-pal[i]]==tmp[i+pal[i]]) pal[i]++;
if(i+pal[i]-1>mx) mx=i+pal[i]-1,id=i;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
while(cin>>s+1)
{
n=strlen(s+1);ans=0;
ins();
manacher();
for(rll i=1;i<=n;i++) a[i].l=i-pal[i]+1,a[i].r=i+pal[i]-1;
sort(a+1,a+n+1);
rll now=1,far=1;
while(a[now].l<=1)
{
if(a[now].r>a[far].r) far=now;
now++;
}
while(now<=n)
{
ans++;
rll tmp=far;
while(a[now].l<=a[far].r)
{
if(a[now].r>a[tmp].r) tmp=now;
now++;
}
far=tmp;
}
cout<<ans-1<<endl;
}
return 0;
}
D.序列
维护正序列和反序列两个ST表,来维护前缀的最小值.
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define maxn 500001
#define rll rg ll
using namespace std;
struct node
{
ll l,r,id;
inline friend bool operator<(node a,node b)
{
return a.l>b.l;
}
}a[maxn];
ll n,num,tot;
ll p[maxn],f[maxn];
ll mn1[maxn][20],mn2[maxn][20];
ll st[maxn],ed[maxn];
ll tmp1[maxn],tmp2[maxn];
vector<ll> g[maxn];
priority_queue<node> q;
inline ll getmn1(ll l,ll r)
{
if(l==r) return l;
rll t=log2(r-l+1);
if(p[mn1[l][t]]<p[mn1[r-(1<<t)+1][t]]) return mn1[l][t];
else return mn1[r-(1<<t)+1][t];
}
inline ll getmn2(ll l,ll r)
{
if(l==r) return l;
rll t=log2(r-l+1);
if(p[mn2[l][t]]<p[mn2[r-(1<<t)+1][t]]) return mn2[l][t];
else return mn2[r-(1<<t)+1][t];
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
for(rll i=1;i<=n;i++)
{
cin>>p[i];
if(i&1) mn1[i][0]=i,mn2[i][0]=n+1;
else mn1[i][0]=n+1,mn2[i][0]=i;
}
p[n+1]=0x7fffffff;
for(rll j=1;j<=19;j++)
for(rll i=1;i+(1<<j)<=n+1;i++)
{
if(p[mn1[i][j-1]]<p[mn1[i+(1<<(j-1))][j-1]]) mn1[i][j]=mn1[i][j-1];
else mn1[i][j]=mn1[i+(1<<(j-1))][j-1];
if(p[mn2[i][j-1]]<p[mn2[i+(1<<(j-1))][j-1]]) mn2[i][j]=mn2[i][j-1];
else mn2[i][j]=mn2[i+(1<<(j-1))][j-1];
}
st[1]=1;ed[1]=n;num=1;
while(tot<num)
{
if(!f[++tot]) f[tot]=f[tot-1];
g[f[tot]].push_back(tot);
rll l=st[tot],r=ed[tot];
if(l&1) tmp1[tot]=getmn1(l,r);
else tmp1[tot]=getmn2(l,r);
if(l&1) tmp2[tot]=getmn2(tmp1[tot]+1,r);
else tmp2[tot]=getmn1(tmp1[tot]+1,r);
a[tot].id=tot;a[tot].l=p[tmp1[tot]];a[tot].r=p[tmp2[tot]];
rll t=num;
if(tmp1[tot]!=l) st[++num]=l,ed[num]=tmp1[tot]-1;
if(tmp2[tot]!=tmp1[tot]+1) st[++num]=tmp1[tot]+1,ed[num]=tmp2[tot]-1;
if(tmp2[tot]!=r) st[++num]=tmp2[tot]+1,ed[num]=r;
if(t!=num) f[t+1]=tot;
}
q.push(a[1]);
while(!q.empty())
{
rll t=q.top().id;q.pop();
cout<<a[t].l<<' '<<a[t].r<<' ';
for(rll i=0;i<g[t].size();i++) q.push(a[g[t][i]]);
}
return 0;
}
--END--

浙公网安备 33010602011771号
我的博客: 𝟷𝙻𝚒𝚞
本文链接: https://www.cnblogs.com/1Liu/p/16525066.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!