2024初三集训模拟测试3
-
T1 排序:
显然贪心。
将
1ll*a[i]*a[i-1]
\(\to\)1ll*(a[i]*a[i-1])
囍爆零CODE
#include<bits/stdc++.h> using namespace std; using llt=long long; using ull=unsigned long long; #define For(i,a,b,c) for(int i=(a);i<=(b);i+=(c)) #define For_(i,a,b,c) for(int i=(a);i>=(b);i-=(c)) const int N=1e5+3; int n,a[N<<2]; namespace IO{ template<class T> inline void write(T x){ static T st[45];T top=0;if(x<0)x=-x,putchar('-'); do{st[top++]=x%10;}while(x/=10);while(top)putchar(st[--top]^48); } template<class T> T READ_NONPARAMETRIC_INIT; template<class T = int> inline T read(T &x=READ_NONPARAMETRIC_INIT<T>){ char s=getchar();x=0;bool pd=false;while(s<'0'||'9'<s){if(s=='-') pd=true;s=getchar();} while('0'<=s&&s<='9'){x=x*10+(s^48),s=getchar();} return (pd?(x=-x):x); } } namespace IO{ char NL_C; double NL_F; long double NL_LF; inline char read(char &c){c=getchar();while(c<33||c>126) c=getchar();return c;} template<int MAXSIZE=INT_MAX> inline int read(char* c){ char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c[pos++]=s,s=getchar();c[pos]='\0';return pos; } template<int MAXSIZE=INT_MAX> inline int read(string &c){ c.clear();char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c.push_back(s),s=getchar(),pos++;return pos; } inline double read(double &x){scanf("%lf",&x);return x;} inline long double read(long double &x){scanf("%Lf",&x);return x;} template<class T,class... Args> inline void read(T& x,Args&... args){read(x);read(args...);} inline void write(char c){putchar(c);} inline void write(char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} inline void write(string &c){int len=c.size();For(i,0,len-1,1) putchar(c[i]);} inline void write(const char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} template<int PRECISION=6> inline void write(double x){printf("%.*lf",PRECISION,x);} template<int PRECISION=6> inline void write(long double x){printf("%.*Lf",PRECISION,x);} template<class T> inline void Write(T x){write(x),putchar(' ');} inline void Write(char c){write(c);if(c!='\n') putchar(' ');} inline void Write(char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} inline void Write(string &c){write(c);if(c[c.size()-1]!='\n') putchar(' ');} inline void Write(const char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);} template<class T,class... Args> inline void Write(T x,Args... args){Write(x);Write(args...);} } using namespace IO; int main(){ #ifndef ONLINE_JUDGE freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif read(n); For(i,1,n<<2,1) read(a[i]); sort(a+1,a+(n<<2)+1); llt ans=0; For(i,1,n,1) ans-=1ll*a[i]*a[(n<<1)-i+1]; For_(i,n<<2,(n<<1)+1,2) ans+=1ll*a[i]*a[i-1]; write(ans); }
-
T2 牛吃草:
显然二分答案。
考虑 \(dp\) 验证。
设 \(dp[i][1/0]\) 表示在前 \(i\) 个选、不选的方案数。
显然转移。
但是要单调队列优化,
因为有个常数不好转移,可以同一加上 \(n-i\),再在查询时减掉。
CODE
#include<bits/stdc++.h> using namespace std; using llt=long long; using ull=unsigned long long; #define For(i,a,b,c) for(int i=(a);i<=(b);i+=(c)) #define For_(i,a,b,c) for(int i=(a);i>=(b);i-=(c)) const int N=5e5+3; int n,w[N],s,dp[N][2],que[N],hd,tl=1; namespace IO{ template<class T> inline void write(T x){ static T st[45];T top=0;if(x<0)x=-x,putchar('-'); do{st[top++]=x%10;}while(x/=10);while(top)putchar(st[--top]^48); } template<class T> T READ_NONPARAMETRIC_INIT; template<class T = int> inline T read(T &x=READ_NONPARAMETRIC_INIT<T>){ char s=getchar();x=0;bool pd=false;while(s<'0'||'9'<s){if(s=='-') pd=true;s=getchar();} while('0'<=s&&s<='9'){x=x*10+(s^48),s=getchar();} return (pd?(x=-x):x); } } namespace IO{ char NL_C; double NL_F; long double NL_LF; inline char read(char &c){c=getchar();while(c<33||c>126) c=getchar();return c;} template<int MAXSIZE=INT_MAX> inline int read(char* c){ char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c[pos++]=s,s=getchar();c[pos]='\0';return pos; } template<int MAXSIZE=INT_MAX> inline int read(string &c){ c.clear();char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c.push_back(s),s=getchar(),pos++;return pos; } inline double read(double &x){scanf("%lf",&x);return x;} inline long double read(long double &x){scanf("%Lf",&x);return x;} template<class T,class... Args> inline void read(T& x,Args&... args){read(x);read(args...);} inline void write(char c){putchar(c);} inline void write(char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} inline void write(string &c){int len=c.size();For(i,0,len-1,1) putchar(c[i]);} inline void write(const char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} template<int PRECISION=6> inline void write(double x){printf("%.*lf",PRECISION,x);} template<int PRECISION=6> inline void write(long double x){printf("%.*Lf",PRECISION,x);} template<class T> inline void Write(T x){write(x),putchar(' ');} inline void Write(char c){write(c);if(c!='\n') putchar(' ');} inline void Write(char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} inline void Write(string &c){write(c);if(c[c.size()-1]!='\n') putchar(' ');} inline void Write(const char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);} template<class T,class... Args> inline void Write(T x,Args... args){Write(x);Write(args...);} } using namespace IO; namespace DQ{ struct Q{int t,id;}que[N]; int hd=1,tl=0; inline void Clr(){hd=1,tl=0;} inline void Add(int x,int id){ while(hd<=tl&&que[tl].t<x) tl--; que[++tl]={x,id}; } inline int Get(int l){ while(hd<=tl&&que[hd].id<l) hd++; if(hd>tl) return 0; return que[hd].t; } } inline bool check(int sz){ memset(dp,0,sizeof dp); DQ::Clr(); For(i,1,n,1){ if(i>=sz) DQ::Add(max(dp[i-sz][1],dp[i-sz][0])+n-(i-sz),i-sz); dp[i][0]=max(dp[i-1][1],dp[i-1][0]); dp[i][1]=max(dp[i][1],DQ::Get(i-w[i])+i-n); } if(max(dp[n][0],dp[n][1])<s) return 0; else return 1; } int main(){ #ifndef ONLINE_JUDGE freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif read(n); For(i,1,n,1) read(w[i]); read(s);s=ceil(n*1.0/100*s); int l=1,r=n; while(l<=r){ int mid=(l+r)>>1; if(check(mid)) l=mid+1; else r=mid-1; } write(r); }
-
T3 树上的宝藏:
考虑先不更换,显然树形 DP。
因为只能换一条,可以考虑换根,枚举到 \(u\) 子节点 \(v\) 时转移。
这里用了 \(dp_{0/1}\) 表示不更换以 \(1\) 为根选、不选的方案数,\(s_{u,0/1}\) 表示不更换以 \(u\) 为根选、不选的方案,\(ans_{u,0/1}\) 表示将 \(fa_u \to u\) 替换后选、不选的方案。
可以少用一个,但无所谓。
-
T4 MEX:
不会,先咕了。