Codeforces Round #353 (Div. 2)
A.首先判断c==0?true的话判断a==b。否的话判断(b-a)与c是否同号,能否整除。
/* ID: onlyazh1 LANG: C++ TASK: test */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e6+7; int main(){ ll a,b,c; cin>>a>>b>>c; if(c==0) cout<<(a==b?"YES":"NO")<<endl; else{ if((b-a)%c==0&&(b-a)/c>=0) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
B.设mx为a+b,a+c,b+d,c+d中的最大值。mi为a+b,a+c,b+d,c+d中的最小值。则答案就是n*max(0,(n+mi-mx))。注意n+mi-mx可能为负。
/* ID: onlyazh1 LANG: C++ TASK: test */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e6+7; int main(){ ll n,a,b,c,d; cin>>n>>a>>b>>c>>d; ll mi=min(a+b,a+c); mi=min(mi,min(b+d,c+d)); ll mx=max(a+b,a+c); mx=max(mx,max(b+d,c+d)); cout<<n* max(0ll,(n+mi-mx))<<endl; return 0; }
C.看了题解才会的。假设一个长度为l,连续和为0的段。那么我们的操作应该是l-1次。假设我们把现在的序列分成了k个连续和为0的段。那么我们的操作应该是n-k次。那么我们应该让k最大。那么前缀和中出现的最大次数就是我们的k。
/* ID: onlyazh1 LANG: C++ TASK: test */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e6+7; int cnt[100100]; int main(){ //ifstream cin("in.txt"); int n; cin >> n; map<long long, int> d; long long sum = 0; int ans = n - 1; for (int i = 0; i < n; i++) { int t; cin >> t; sum += t; d[sum]++; ans = min(ans, n - d[sum]); } cout << ans << endl; return 0; }
D.用一个set记录到第i个数字为止,已经插入了的数字。那么第i个数字必然插在set中与他相邻的两个数字的某一个下面。容易发现,新的数字应该插在深度较深的数字下面。证明暂时不会。
/* ID: onlyazh1 LANG: C++ TASK: test */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e6+7; set<int> S; map<int,int> M; int val[maxn]; int ans[maxn]; int dep[maxn]; int main(){ int n,t,idx; set<int>::iterator pre,nex,tmp; cin>>n; for(int i=0;i<n;i++){ cin>>t;M[t]=i;val[i]=t; if(i){ nex=S.lower_bound(t); if(nex==S.begin()) ans[i]=M[*nex]; else{ tmp=nex;pre=(--nex);nex=tmp; ans[i]= dep[M[*pre]]>dep[M[*nex]]?M[*pre]:M[*nex]; } } S.insert(t); dep[i]=dep[ans[i]]+1; } for(int i=1;i<n;i++) cout<<val[ans[i]]<<" "; cout<<endl; return 0; }
E.
/* ID: onlyazh1 LANG: C++ TASK: test */ #include<bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long ll; const int maxn=1e6+7; pair<int,int> mx[maxn<<2]; int to[maxn]; ll sum[maxn]; int n; void PushUP(int rt){ if(mx[rt<<1].first>=mx[rt<<1|1].first) mx[rt]=mx[rt<<1]; else mx[rt]=mx[rt<<1|1]; } void update(int p,int x,int l,int r,int rt){ if(l==r){ mx[rt].first=x; mx[rt].second=l; return ; } int m=(l+r)/2; if(p<=m) update(p,x,lson); else update(p,x,rson); PushUP(rt); } pair<int,int> query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R){ return mx[rt]; } int m=(l+r)/2; pair<int,int> ret1,ret2; ret1.first=ret2.first=-1; if(L<=m) ret1=query(L,R,lson); if(R>m) ret2=query(L,R,rson); return ret1.first>=ret2.first?ret1:ret2; } ll add(int x){ if(x==n) return sum[x]=0; pair<int,int> px=query(x,to[x],1,n,1); if(px.second==x) return sum[x]=(n-x)+(sum[px.first]==-1?add(px.first):sum[px.first]); else return sum[x]=(n-x+px.second-to[x])+(sum[px.second]==-1?add(px.second):sum[px.second]); } int main(){ //ifstream cin("in.txt"); memset(sum,-1,sizeof(sum)); cin>>n; for(int i=1;i<n;i++){ cin>>to[i]; update(i,to[i],1,n,1); } // pair<int,int> px=query(1,to[1]-1,1,n,1); // cout<<px.first<<" "<<px.second<<endl; for(int i=1;i<n;i++){ if(sum[i]==-1) add(i); // for(int j=1;j<n;j++) // cout<<sum[j]<<" "; // cout<<endl; } // for(int j=1;j<n;j++) // cout<<sum[j]<<" "; // cout<<endl; ll ans=0; for(int i=1;i<n;i++) ans+=sum[i]; cout<<ans<<endl; return 0; }