Codeforces Round #679 Div.1
幸亏没打。。。
A
从小到大排序,模拟。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<climits> #include<set> #define pii pair<int,int> #define fi first #define se second #define pb push_back #define mp make_pair using namespace std; inline int read(){ int f=1,ans=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } const int MAXN=1e5+11; int N,A[7],B[7][MAXN]; multiset<int> s; void Ins(int w){/*cerr<<"Ins:"<<w<<endl;*/s.insert(w);return;} void Del(int w){/*cerr<<"Del:"<<w<<endl;*/s.erase(s.find(w));return;} int Qmax(){return *(--s.end());} struct Node{int w;pii p;}tmp[MAXN*7]; bool cmp(Node x1,Node x2){return x1.w<x2.w;} int Ps[MAXN],Ans=INT_MAX,tot; int main(){ //freopen("in2.txt","r",stdin); for(int i=1;i<=6;i++) A[i]=read();sort(A+1,A+7); N=read(); for(int i=1;i<=N;i++) {int x=read();for(int j=1;j<=6;j++) B[j][i]=x-A[j];} for(int i=1;i<=6;i++) for(int j=1;j<=N;j++){++tot;tmp[tot].w=B[i][j],tmp[tot].p=mp(i,j);} sort(tmp+1,tmp+tot+1,cmp); int ps=1;for(int i=1;i<=N;i++) Ins(B[6][i]),Ps[i]=6;bool ff=1; if(N==1){printf("%d\n",0);return 0;} while(ps<=tot){ int l=ps,r;for(r=ps;tmp[r].w==tmp[l].w;r++);r--; //cerr<<"l:"<<l<<" r:"<<r<<endl; for(int i=l;i<=r;i++) { Del(tmp[i].w),Ans=min(Ans,Qmax()-tmp[l].w),Ins(tmp[i].w); //cerr<<"res:"<<Qmax()-tmp[l].w<<endl; //if(Ans==-199) return 0; } for(int i=l;i<=r;i++){ Del(tmp[i].w),Ps[tmp[i].p.se]--;if(!Ps[tmp[i].p.se]) ff=0; Ins(B[Ps[tmp[i].p.se]][tmp[i].p.se]); }if(!ff) break; ps=r+1; } printf("%d\n",Ans);return 0; }
B
构造。发现构造的是一个必要解,检验一下正确性。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<climits> #include<set> #define pii pair<int,int> #define fi first #define se second #define pb push_back #define mp make_pair using namespace std; inline int read(){ int f=1,ans=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } const int MAXN=2e5+11; char str[3];int N,sta[MAXN],Ans[MAXN],tot; set<int> s; void Ins(int w){s.insert(w);return;} void Del(int w){s.erase(s.find(w));return;} int Qmax(){return *(--s.end());} struct node{ int opt,w; }tmp[MAXN];int cnt; int main(){ //freopen("in1.txt","r",stdin); N=read();for(int i=1;i<=N;i++) Ins(i); for(int cas=1;cas<=2*N;cas++){ scanf("%s",str+1); if(str[1]=='+'){tmp[++cnt].opt=0;sta[++sta[0]]=++tot;Ans[sta[sta[0]]]=Qmax();Del(Qmax());continue;} else{ int x=read(); tmp[++cnt].opt=1,tmp[cnt].w=x; if(!sta[0]){printf("NO\n");return 0;} int ps=sta[sta[0]]; if(Ans[ps]<x){printf("NO\n");return 0;} if(Ans[ps]==x) {sta[0]--;continue;} Ins(Ans[ps]);sta[0]--; if(s.find(x)!=s.end()){Del(x);Ans[ps]=x;continue;} {printf("NO\n");return 0;} } } s.clear();int ps=1; for(int i=1;i<=2*N;i++){ if(!tmp[i].opt) {s.insert(Ans[ps]);ps++;continue;} else{ int x=*s.begin(); if(x!=tmp[i].w){printf("NO\n");return 0;} s.erase(x); } } printf("YES\n"); for(int i=1;i<=N;i++) printf("%d ",Ans[i]);printf("\n"); return 0; }
C
首先当 $a>bc$ 时显然答案为 $-1$ 。
而我们只需要考虑在 $c$ 之前的,因为如果过期了那么还不如从后一段开始优。
如图,记 $k=\dfrac{a}{bd}$ ,则答案为 $a(k+1)-\dfrac{k*(k+1)}{2}bd$。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<climits> #define pii pair<int,int> #define fi first #define se second #define pb push_back #define mp make_pair #define int long long using namespace std; inline int read(){ int f=1,ans=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } int A,B,C,D,T; signed main(){ T=read(); while(T--){ A=read(),B=read(),C=read(),D=read(); if(A>B*C){printf("-1\n");continue;} if(C<=D){printf("%lld\n",A);continue;} int K=A/(B*D); printf("%lld\n",A*(K+1)-(1+K)*K/2*B*D); }return 0; }
D
对于符合条件的最长链肯定有一个端点在直径的两个端点上。证明可以考虑相交部分奇偶讨论,可以发现直径一定优于其他。
则直接将两个根摘出来,线段树维护即可。
#include<iostream> #include<cstring> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<algorithm> #include<climits> #include<map> #define pii pair<int,int> #define pb push_back #define mp make_pair #define fi first #define se second using namespace std; inline int read(){ int f=1,ans=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } const int MAXN=5e5+11; int N;vector<pii> vec[MAXN]; map<pii,int> M; struct Tree{ int rt,siz[MAXN],dfn[MAXN],dis[MAXN],rev[MAXN],Id[MAXN],dep[MAXN]; void dfs(int u,int fath){ siz[u]=1;dfn[u]=++dfn[0];dep[u]=dep[fath]+1;rev[dfn[0]]=u; if(fath) Id[M[mp(u,fath)]]=u; for(auto pp:vec[u]){if(pp.fi!=fath){dis[pp.fi]=dis[u]+pp.se;dfs(pp.fi,u);siz[u]+=siz[pp.fi];}} return; } int Maxn[2][MAXN<<2],tag[MAXN<<2]; void build(int k,int l,int r){ if(l==r){Maxn[dis[rev[l]]&1][k]=dep[rev[l]];return;} int mid=(l+r)>>1;build(k<<1,l,mid),build(k<<1|1,mid+1,r); Maxn[0][k]=max(Maxn[0][k<<1],Maxn[0][k<<1|1]); Maxn[1][k]=max(Maxn[1][k<<1],Maxn[1][k<<1|1]); return; } void pushdown(int k){ if(!tag[k]) return; if(!(tag[k]&1)){tag[k<<1]+=tag[k],tag[k<<1|1]+=tag[k];tag[k]=0;return;} swap(Maxn[0][k<<1],Maxn[1][k<<1]),swap(Maxn[0][k<<1|1],Maxn[1][k<<1|1]); tag[k<<1]+=tag[k],tag[k<<1|1]+=tag[k];tag[k]=0;return; } void Add(int k,int l,int r,int x,int y,int w){ if(x<=l&&r<=y){tag[k]+=w;swap(Maxn[0][k],Maxn[1][k]);return;} pushdown(k);int mid=(l+r)>>1; if(x<=mid) Add(k<<1,l,mid,x,y,w); if(mid<y) Add(k<<1|1,mid+1,r,x,y,w); Maxn[0][k]=max(Maxn[0][k<<1],Maxn[0][k<<1|1]); Maxn[1][k]=max(Maxn[1][k<<1],Maxn[1][k<<1|1]); return; } int Qmax(){return Maxn[0][1];} void init(){memset(Maxn,-127/3,sizeof(Maxn)),memset(tag,0,sizeof(tag));dfs(rt,0);build(1,1,N);return;} void Add(int id){int u=Id[id];Add(1,1,N,dfn[u],dfn[u]+siz[u]-1,1);return;} void Del(int id){int u=Id[id];Add(1,1,N,dfn[u],dfn[u]+siz[u]-1,-1);return;} void print(){ for(int i=1;i<=N;i++) printf("%d %d\n",dis[i],rev[i]);printf("\n"); return; } }S1,S2; int dep[MAXN],rt1,rt2,Q,sta[MAXN]; void dfs(int u,int fath){dep[u]=dep[fath]+1;for(auto pp:vec[u]) if(pp.fi!=fath) dfs(pp.fi,u);} int main(){ //freopen("A.in","r",stdin); N=read();for(int i=1;i<N;i++){int u=read(),v=read(),w=read();sta[i]=w;M[mp(u,v)]=M[mp(v,u)]=i;vec[u].pb(mp(v,w)),vec[v].pb(mp(u,w));} dfs(1,0);int Max=1,ps=1;for(int i=2;i<=N;i++) if(dep[i]>Max) Max=dep[i],ps=i; rt1=ps;dfs(rt1,0);Max=1,ps=rt1;for(int i=1;i<=N;i++) if(dep[i]>Max) Max=dep[i],ps=i; rt2=ps; S1.rt=rt1,S2.rt=rt2;S1.init(),S2.init(); //S1.print(); //S1.print();return 0; Q=read(); while(Q--){ int x=read(); //cerr<<sta[x]<<endl; if(!sta[x]){S1.Add(x),S2.Add(x);sta[x]^=1;} else if(sta[x]){S1.Del(x),S2.Del(x);sta[x]^=1;} int res1=S1.Qmax(),res2=S2.Qmax(); printf("%d\n",max(res1,res2)-1); //return 0; }return 0; }