Multi school sprint NOIP 20211110 simulation (27)
emmm... After the test, I found that T1 was just greedy. I cut it directly in 40 minutes, and then I opened T2. I thought of a \ (O(n^2) \) violence. As a result, I didn't think of optimization, and then I jumped
The starch content of T3 is about 6 or 70 points. I'm going to look at T4 after writing T4, and then I'll look at T4. 20 points of T4 are for nothing
Then I got it in five minutes. Then I didn't have any ideas about other parts. Then I went back to T3. The time was about 10:20. I thought I could solve it in an hour,
Thinking big talk is probably a two-dimensional partial order problem on the tree. I am bent on the merging of subtrees emmm.. But in fact, the content exclusion play is better
After adjusting it for a long time, it was found that the merger was wrong, and it would be too late.
Watching the hand get 70 points fly away, it's not a taste in my heart
Finally, at 100 + 50 + 10 + 20, I found that T2 is an sb question. I thought of it after the exam. I knew I shouldn't have put all my time on T3. I still have to arrange my time reasonably in the future
T1 open
First of all, the order of \ (B {I} \) can be randomly disrupted, so you can first find the \ (dealt \) of all \ (a {I} \) and sort them to select the best
As for \ (a_{i} \), it is found that the small elements change according to whether the larger elements appear, so the larger elements can be changed first, and the optimal result is certain regardless of the change order
Therefore, according to the nature of the inequality, it can be proved that the one with large change first is not inferior
Then you can open two set s, one to maintain the current element and the other to maintain the \ (a_{i}+1 \) that has not appeared in all the current elements
Judge whether this element has appeared in the first set. If it has, then \ (lower\ bound \) a minimum position that does not appear, and then delete it
Then just count the answers directly
#include<bits/stdc++.h> #define ull unsigned long long using namespace std; const int Mxdt=1e5; inline char gc() { static char buf[Mxdt],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,Mxdt,stdin),p1==p2)?EOF:*p1++; } inline int read() { int t=0,f=0;char v=gc(); while(v<'0')f|=(v=='-'),v=gc(); while(v>='0')t=(t<<3)+(t<<1)+v-48,v=gc(); return f?-t:t; } const int maxn=1e6+5; int a[maxn],b[maxn],n; bool cmp(int a,int b){return a>b;} set<int>st,ts;ull ans; int tmp[maxn],top; signed main() { freopen("openhook.in","r",stdin); freopen("openhook.out","w",stdout); n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) b[i]=read(); sort(b+1,b+1+n);sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++) { if(st.find(a[i])==st.end()) { st.insert(a[i]); if(ts.find(a[i])!=ts.end()) ts.erase(ts.find(a[i])); if(st.find(a[i]+1)==st.end()) ts.insert(a[i]+1); } else { int it=*ts.lower_bound(a[i]); tmp[++top]=it-a[i]; st.insert(it);ts.erase(ts.find(it)); if(st.find(it+1)==st.end()) ts.insert(it+1); } } sort(tmp+1,tmp+1+top,cmp); for(int i=1;i<=top;i++) ans=ans+1ull*tmp[i]*b[i]; cout<<ans<<endl; }
T2 thirty seven million
A sb question, but most of the time in the examination room was given to T3. I was very angry
First, you can have a relatively simple dp
Set \ (DP {i} \) as the number of schemes grouped by the number of previous \ (i \), and the transfer is \ (DP {i} = DP {K} [Bo {K + 1, i} = = 1] \)
Where \ (bo_{i,j} \) indicates that all numbers less than or equal to global \ (mex \) occur from I to j
Then it is found that you can prefix and optimize it casually, and then it will be \ (O(n) \)
#include<bits/stdc++.h> using namespace std; const int Mxdt=1e6; inline char gc() { static char buf[Mxdt],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,Mxdt,stdin),p1==p2)?EOF:*p1++; } inline int read() { int t=0,f=0;char v=gc(); while(v<'0')f|=(v=='-'),v=gc(); while(v>='0')t=(t<<3)+(t<<1)+v-48,v=gc(); return f?-t:t; } const int mod=1e9+7; const int maxn=37000010; int tong[maxn],f[maxn],a[maxn],n,x,y; inline int ksm(int x,int y) { int res=1;x=x%mod; for(;y;y>>=1){if(y&1)res=1ll*res*x%mod;x=1ll*x*x%mod;} return res; } signed main() { freopen("clods.in","r",stdin); freopen("clods.out","w",stdout); int t=read(); while(t--) { n=read(); if(n<37000000) for(int i=1;i<=n;i++)a[i]=read(),tong[i]=0; else { x=read();y=read();a[1]=0;tong[a[1]]++; for(int i=2;i<=n;i++) a[i]=(1ll*a[i-1]*x+y+i)&262143,tong[a[i]]++; } int gen=0; if(n==37000000){for(int i=0;i<=n;i++){if(!tong[i]){gen=i;break;}tong[i]=0;}} else{ tong[0]=0; for(int i=1;i<=n;i++)tong[a[i]]++; for(int i=0;i<=n;i++)if(!tong[i]){gen=i;break;} } int tmp=0,ks=0;for(int i=0;i<=n;i++)tong[i]=0,f[i]=0; for(int i=1;i<=n;i++) { ++tong[a[i]]; while(tong[tmp]) tmp++; if(tmp==gen){ks=i;break;} } int l=1;f[ks]=1; for(int i=ks+1;i<=n;i++) { ++tong[a[i]];f[i]=1; while(((tong[a[l]]>1&&a[l]<gen)||a[l]>gen)&&l<i) {tong[a[l]]--;l++;}f[i]=(f[i]+f[l-1]+f[i-1])%mod; } printf("%d\n",(f[n]-f[n-1]+mod)%mod); } }
T3
A kruskal reconstruction tree can be built. In \ (t {1} \), the \ (LCA \) of \ (x,y \) is the smallest between \ (x,y \)
\(t {2} \) is the largest, and then \ (dfs+BIT \) is solved perfectly
#include<bits/stdc++.h> #define ll long long using namespace std; const int Mxdt=100000; inline char gc(){ static char buf[Mxdt],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,Mxdt,stdin),p1==p2)?EOF:*p1++; } inline int read(){ int t=0,f=0;char v=gc(); while(v<'0')f|=(v=='-'),v=gc(); while(v>='0')t=(t<<3)+(t<<1)+v-48,v=gc(); return f?-t:t; } const int maxn=2e6+5; int f[maxn]; inline int getfa(int x){return f[x]==x?x:f[x]=getfa(f[x]);} int minn[maxn],maxx[maxn],siz[maxn],n,dfn[maxn]; vector<int>p[maxn]; int head[maxn],num; struct edge{int to,nxt;}e[maxn<<1]; inline void add(int x,int y) {e[++num]=(edge){y,head[x]};head[x]=num;} struct szsz{ #define lowbit(x) (x&(-x)) int c[maxn]; inline void update(int x,int val) {for(;x<=n;x+=lowbit(x))c[x]+=val;} inline int query(int x) {int res=0;for(;x;x-=lowbit(x))res+=c[x];return res;} }T; inline void merge1(int x,int y) { int fx=getfa(x),fy=getfa(y); if(fx==fy) return ; if(fx<fy) f[fy]=fx,add(fx,fy); else f[fx]=fy,add(fy,fx); } inline void merge2(int x,int y) { int fx=getfa(x),fy=getfa(y); if(fx==fy) return ; if(fx>fy) f[fy]=fx,add(fx,fy); else f[fx]=fy,add(fy,fx); } int cnt=0;ll ans=0; inline void dfs1(int x) { dfn[x]=++cnt;siz[x]=1; for(int i=head[x];i;i=e[i].nxt) {int y=e[i].to;dfs1(y);siz[x]+=siz[y];} } inline void dfs2(int x) { ans+=T.query(siz[x]+dfn[x]-1)-T.query(dfn[x]-1); T.update(dfn[x],1); for(int i=head[x];i;i=e[i].nxt){int y=e[i].to;dfs2(y);} T.update(dfn[x],-1); } signed main() { freopen("charity.in","r",stdin); freopen("charity.out","w",stdout); n=read(); for(int i=1;i<=n;i++) { f[i]=i; int x=read(); if(i!=1) { p[x].push_back(i); p[i].push_back(x); } } for(int i=n;i>=1;i--) for(auto y:p[i]) if(y>i) merge1(y,i); dfs1(1); for(int i=1;i<=n;i++)f[i]=i;num=0;memset(head,0,sizeof(head)); for(int i=1;i<=n;i++) for(auto y:p[i]) if(y<i) merge2(y,i); dfs2(n); printf("%lld\n",ans); }
T4 happy beans
At most M points will change their distance, so run dij for these m points, and each edge will be relaxed only once, so the complexity is \ (O(m^2log(m)) \)
#include<bits/stdc++.h> #define ll 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 maxn=1e5+5; const ll inf=1e18+7; struct edge{int to,w;}; struct node{ int id,op;ll d; bool operator<(node x)const{return d>x.d;} }; ll ans,dis[maxn],mn;int c[maxn],pos[maxn],fa[maxn],n,m,sq[maxn],fl[maxn],C,fz; inline int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);} vector<edge>vec[maxn];priority_queue<node>q; inline void dij(int x) { for(int i=1;i<=C;i++) fa[i]=i,dis[i]=inf; fa[C+1]=C+1;q.push((node){x,0,dis[x]=0}); while(!q.empty()) { node e=q.top();q.pop(); int ps=e.id; if(e.op) { for(auto y:vec[ps]) fl[y.to]=1; for(int i=getfa(1);i<=C;i=getfa(i+1)) if(!fl[i]) { int x=i,w=e.d; if(fa[x]!=x) continue; dis[x]=w;fa[x]=fa[x]+1; q.push((node){x,1,w+c[sq[x]]}); for(auto v:vec[x]) if(dis[v.to]>dis[x]+v.w) q.push({v.to,0,dis[v.to]=dis[x]+v.w}); } for(auto k:vec[ps])fl[k.to]=0; } else { int x=ps,w=e.d; if(fa[x]==x) { dis[x]=w;fa[x]=fa[x]+1; q.push((node){x,1,w+c[sq[x]]}); for(auto v:vec[x]) if(dis[v.to]>dis[x]+v.w) q.push({v.to,0,dis[v.to]=dis[x]+v.w}); } } } } signed main() { freopen("happybean.in","r",stdin); freopen("happybean.out","w",stdout); n=read();m=read();c[0]=1e9; for(int i=1;i<=n;i++)c[i]=read(); for(int i=1;i<=m;i++) { int x=read(),y=read(),z=read(); if(!pos[x]) sq[pos[x]=++C]=x; if(!pos[y]) sq[pos[y]=++C]=y; vec[pos[x]].push_back((edge){pos[y],z}); } for(int i=1;i<=n;i++) if(!pos[i]&&c[fz]>c[i])fz=i; if(fz&&!pos[fz]) sq[pos[fz]=++C]=fz; for(int i=1;i<=n;i++) if(!pos[i])ans+=1ll*c[i]*(n-1); for(int i=1;i<=C;i++) { dij(i);mn=inf; for(int j=1;j<=C;j++) ans+=dis[j],mn=min(mn,dis[j]+c[sq[j]]); ans+=mn*(n-C); } printf("%lld\n",ans); }