Noip模拟100 2021.11.17
直接给我整了个原题大战,出题人四处嫖题就非常离谱。。。
我是小马 桶 ,今天终于一百场了我真开心
T1 饥饿的狐狸
比较水的贪心,不知道为啥洛谷上面评级是紫的。。。。
题意可以转化为规定每次走的位置和一个可以随时到达的原点,要求最大化和最小化行走的距离
显然可以先把\(T\)升序排序
先看当\(W=0\)的情况,比较好想出最小值直接就是\(T_n\),最大值可以通过观察你的全排列的暴力得出结论
最大值的时候直接反复横跳就是答案,其实性感理解的话比较好想出,但是我考场上打了暴力我为什么还要想呢??
这样我们继续考虑原点不是\(0\)的情况,发现还是可以用反复横跳来解决,只不过起点需要找到距离原点最远的点
但是我为了保证贪心正确打了好几个不同的贪心取了最大值,里面还有一个随即贪心。。。。1
最小值的话需要找到离原点最近的两个点,然后分别向最小值和最大值的方向移动即可
注意在累计答案的时候都需要和到原点的距离进行比较,因为如果这时候去原点更优肯定会选择先去一下原点(也就是先喝一口水再吃)
a
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace AE86{
FILE *wsn;
#define gc() p1==p2 and (p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++
char buf[1<<20],*p1=buf,*p2=buf;
auto read=[](){
int x=0,f=1;char ch=gc();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=gc();} return x*f;
};
auto write=[](int x,char opt='\n'){
char ch[20];short len=0;if(x<0)x=~x+1,putchar('-');
do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
for(short i=len-1;i>=0;--i){putchar(ch[i]);}putchar(opt);
};
#define mzs
}using namespace AE86;
const int NN=1e6+5;
int n,w,t[NN];
auto task=[](int sm=0){
sort(t+1,t+n+1);int it1=1,it2=n,pre=0;
for(int i=1;i<=n;i++){
if(i&1){
sm+=max(abs(t[it2]-pre),abs(t[it2]-w));
pre=t[it2--];
}else{
sm+=max(abs(t[it1]-pre),abs(t[it1]-w));
pre=t[it1++];
}
}
printf("%lld %lld\n",t[n],sm);
};
int mx,mn;
bool vis[NN];
auto getnum=[](){
int x=rand()%n+1;
while(vis[x]) x=rand()%n+1;
vis[x]=1; return x;
};
auto greedymax=[](){
int itl=1,itr=n,pre=w;
int tmp=0;
for(int i=1;i<=n;i++){
if(i&1){
tmp+=max(abs(t[itl]-pre),abs(t[itl]-w));
pre=t[itl++];
}else{
tmp+=max(abs(t[itr]-pre),abs(t[itr]-w));
pre=t[itr--];
}
}
mx=tmp; itl=1; itr=n; pre=w; tmp=0;
for(int i=1;i<=n;i++){
if(!(i&1)){
tmp+=max(abs(t[itl]-pre),abs(t[itl]-w));
pre=t[itl++];
}else{
tmp+=max(abs(t[itr]-pre),abs(t[itr]-w));
pre=t[itr--];
}
}
mx=max(mx,tmp);
write(mx);
};
auto greedymin=[](){
int pre=w,pos=1;
while(t[pos]<w&&pos<n) ++pos;
if(pos==1){
for(int i=1;i<=n;i++)
mn+=t[i]-pre,pre=t[i];
return write(mn,' '),void();
}else if(pos==n&&t[n]<=w){
for(int i=n;i;i--)
mn+=pre-t[i],pre=t[i];
return write(mn,' '),void();
}
int pps=pos-1; if(pos+1==w&&pos==w) pos++,pps=pos-1;
int itl=pps,itr=pos,tmp=0;
for(int i=pos;i<=n;i++) tmp+=min(abs(t[i]-pre),abs(t[i]-w)),pre=t[i];
pre=w;
for(int i=pps;i;i--) tmp+=min(abs(t[i]-pre),abs(t[i]-w)),pre=t[i];
mn=tmp;
write(mn,' ');
};
namespace WSN{
inline short main(){
wsn=freopen("a.in","r",stdin);
wsn=freopen("a.out","w",stdout);
srand(time(NULL)^clock());
n=read(); w=read();
for(int i=1;i<=n;i++){
t[i]=read();
}if(!w) return task(),0;
sort(t+1,t+n+1);
greedymin(); greedymax();
return 0;
}
}
signed main(){return WSN::main();}
T2 保险箱
感觉提议描述很不清楚,考试的时候根本不知道他要我求什么。。。
显然考试之后还有很多人跟我是一样的,都理解错题意了。。。
所以这题直接去洛谷上面瞅题解吧,没啥好说的了,我反正是伞兵做法。。。。(逃)
b
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace AE86{
FILE *wsn;
#define gc getchar
auto read=[](){
int x=0,f=1;char ch=gc();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=gc();} return x*f;
};
auto write=[](int x,char opt='\n'){
char ch[20];short len=0;if(x<0)x=~x+1,putchar('-');
do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
for(short i=len-1;i>=0;--i){putchar(ch[i]);}putchar(opt);
};
}using namespace AE86;
const int NN=250005;
int n,k,m[NN],tot;
auto check=[](int x){
for(int i=tot;i;i--){
if(!(m[i]%x)) return false;
if(m[i]<x) break;
}return true;
};
inline int gcd(int a,int b){return b?gcd(b,a%b):a;};
namespace WSN{
inline short main(){
wsn=freopen("b.in","r",stdin);
wsn=freopen("b.out","w",stdout);
n=read(); k=read();
for(int i=1;i<=k;i++)m[i]=read();
int rng=gcd(m[k],n);
for(int i=1;i<k;i++)m[i]=gcd(m[i],rng);
sort(m+1,m+k);tot=unique(m+1,m+k)-m-1;
int ans=rng;
for(int i=1;i*i<=rng;i++)if(!(rng%i)){
if(i<ans&&check(i)) ans=i;
if(rng/i<ans&&check(rng/i)) ans=rng/i;
}
write(n/ans);
return 0;
}
}
signed main(){return WSN::main();}
T3 追逐
原题大作战系列
c
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline 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<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
const int NN=1e5+2;
int n,v,p[NN],sum[NN];
int up[NN][101],dw[NN][101],ans;
vector<int> g[NN];
inline void dfs(int f,int x){
sum[x]+=p[f];
for(int i=0;i<g[x].size();i++){
int y=g[x][i];if(y==f) continue;
dfs(x,y); sum[x]+=p[y];
}
}
inline void dp(int f,int x){
for(int i=1;i<=v;i++){
up[x][i]=sum[x];
dw[x][i]=sum[x]-p[f];
}
for(int i=0;i<g[x].size();i++){
int y=g[x][i];
if(y==f) continue;
dp(x,y);
for(int j=1;j<v;j++)
ans=max(ans,up[x][j]+dw[y][v-j]);
for(int j=1;j<=v;j++){
up[x][j]=max(up[x][j],max(up[y][j],up[y][j-1]+sum[x]-p[y]));
dw[x][j]=max(dw[x][j],max(dw[y][j],dw[y][j-1]+sum[x]-p[f]));
}
}
reverse(g[x].begin(),g[x].end());
for(int i=1;i<=v;i++){
up[x][i]=sum[x];
dw[x][i]=sum[x]-p[f];
}
for(int i=0;i<g[x].size();i++){
int y=g[x][i];
if(y==f) continue;
for(int j=1;j<v;j++)
ans=max(ans,up[x][j]+dw[y][v-j]);
for(int j=1;j<=v;j++){
up[x][j]=max(up[x][j],max(up[y][j],up[y][j-1]+sum[x]-p[y]));
dw[x][j]=max(dw[x][j],max(dw[y][j],dw[y][j-1]+sum[x]-p[f]));
}
}
ans=max(ans,max(up[x][v],dw[x][v]));
}
namespace WSN{
inline int main(){
FILE *wsn=freopen("c.in","r",stdin);
wsn=freopen("c.out","w",stdout);
n=read(); v=read(); if(!v) {puts("0");return 0;}
for(int i=1;i<=n;i++) p[i]=read();
for(int i=1;i<n;i++){
int x=read(),y=read();
g[x].push_back(y);
g[y].push_back(x);
}dfs(0,1); dp(0,1);
printf("%lld\n",ans);
return 0;
}
}
signed main(){return WSN::main();}
T4 字符串
我看不懂题解,于是去看了洛谷上的题解
d
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace AE86{
FILE *wsn;
#define gc getchar
auto read=[](){
int x=0,f=1;char ch=gc();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=gc();} return x*f;
};
auto write=[](int x,char opt='\n'){
char ch[20];short len=0;if(x<0)x=~x+1,putchar('-');
do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
for(short i=len-1;i>=0;--i){putchar(ch[i]);}putchar(opt);
};
#define mzs
}using namespace AE86;
const int NN=5e5+5;
int n,q,a[NN],l,r;
char s[NN];
namespace segment_tree{
#define lid (id<<1)
#define rid (id<<1|1)
#define mid ((l+r)>>1)
struct node{
int ls,rs,ms,sm;
node(){ls=rs=ms=sm=0;}
node(int ls,int rs,int ms,int sm):ls(ls),rs(rs),ms(ms),sm(sm){}
node operator+(const node&x)const{
node ret;
ret.ls=max(ls,sm+x.ls);
ret.rs=max(x.rs,x.sm+rs);
ret.ms=max(max(ret.ls,ret.rs),max(x.ls+rs,max(ms,x.ms)));
ret.sm=sm+x.sm;
return ret;
}
}w[NN<<2];
inline void pushup(int id){w[id]=w[lid]+w[rid];}
inline void build(int id,int l,int r){
if(l==r)return w[id]=node(a[l],a[l],a[l],a[l]),void();
build(lid,l,mid);build(rid,mid+1,r);pushup(id);
}
inline node query(int id,int l,int r,int L,int R){
if(L<=l&&r<=R) return w[id]; node ret;
if(L<=mid) ret=query(lid,l,mid,L,R)+ret;
if(R>mid) ret=ret+query(rid,mid+1,r,L,R);
return ret;
}
}
segment_tree::node ans;
auto solve=[](){
l=read(); r=read();ans=segment_tree::query(1,1,n,l,r);
write(ans.ms-ans.sm);
};
namespace WSN{
inline short main(){
wsn=freopen("d.in","r",stdin);
wsn=freopen("d.out","w",stdout);
n=read();scanf("%s",s+1);
for(int i=1;i<=n;i++)if(s[i]=='C') a[i]=1;else a[i]=-1;
segment_tree::build(1,1,n);q=read(); while(q--) solve();
return 0;
}
}
signed main(){return WSN::main();}

浙公网安备 33010602011771号