Codeforces Round #353 (Div. 2)
A:水題
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #defineApb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) usingnamespace std; const double g=10.0,eps=1e-12; const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f; int main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(c==0) { if(a==b)puts("YES"); else puts("NO"); return 0; } if((b-a)%c==0) {if(a>=b&&c<=0)puts("YES"); else if(a<=b&&c>=0)puts("YES"); else puts("NO"); } else puts("NO"); return 0; } /******************** ********************/
B:sb公式題,把公式列出來枚舉即可
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f; int main() { ll n,a,b,c,d; scanf("%lld%lld%lld%lld%lld",&n,&a,&b,&c,&d); ll ans=n; ll te1=a+b,te2=a+c,te3=b+d,te4=c+d; ll te=max(te1,max(te2,max(te3,te4)))-min(te1,min(te2,min(te3,te4))); te=max(0ll,te);te=min(n,te); te=n-te; printf("%lld\n",ans*te); return 0; } /******************** ********************/B
C:題意:給你n個數,每次能把一個數轉移到隔壁,1和n是隔壁,要求最少幾次能把每個數變成0
題解:前綴和維護一下,前綴和相同就代表這一段區間和為0,那麽就可以少轉移一次,map維護一下瞎搞就行了
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; ll a[N],sum[N]; map<ll,ll>ma; int main() { ll n; scanf("%lld",&n); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); sum[i]=sum[i-1]+a[i]; ma[sum[i]]++; } ll ans=n-1; for(auto x:ma)ans=min(ans,n-x.se); printf("%lld\n",max(0ll,ans)); return 0; } /******************** ********************/C
D:題意:給你n個數,依次插入到二叉搜索樹裏,看每個點的父親節點價值是多少
題解:很明顯不能模擬,退化成一條鏈 的時候復雜度O(N^2),所以我們需要用set來維護一下,當插入值是x時,前驅是l,後繼是r,x要麽是l的右兒子,要麽是r的左兒子,,又因為l沒有右兒子和r沒有左兒子不能同時成立,所以找到另一個插入即可.set+upperbound即可
黑體字的證明:假設l沒有右兒子而且r沒有左兒子,而且l,r不能是另一個的祖先(這樣不滿足假設),那麽l,r的公共祖先為a,那麽a要麽是前驅,要麽是後繼,所以假設不成立
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; struct point{ int v; mutable bool l,r; bool operator <(const point &rhs)const{ return v<rhs.v; } }p[N]; set<point>s; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&p[i].v); p[i].l=p[i].r=0; if(i!=1) { auto te=s.upper_bound(p[i]); if(te==s.end()) { te--; (*te).r=1; printf("%d ",(*te).v); } else { if((*te).l==0) { (*te).l=1; printf("%d ",(*te).v); } else { te--; (*te).r=1; printf("%d ",(*te).v); } } } s.insert(p[i]); } puts(""); return 0; } /******************** ********************/D
E:題意:給你n個車站,從i到i+1~a[i]只需要一步,i到j的價值是最少需要走的步數μ(i,j),求每兩個不相同的點的價值和
題解:dp[i]表示∑(i<j<=n)μ(i,j),因為對於路徑i,j,對於i<j<=a[i],為1,否則dis[i]=dis[a[m]]+1,m是i+1到a[i]中a[m]最大的,那麽轉移方程dp[i]=dp[m]+(n-i)-(a[i]-m),m的i+1到a[i]的a[m]最大值,這個可以用線段樹維護
仔細解釋一下轉移方程,dp[m]-(a[i]-m)就是要把m到a[i]的刪掉,因為這個地方從dp[m]可以一步到達,而在dp[i]中也能一步到達,對於i到m的地方dp[i]一步能到達,對於a[i]+1到n的地方,我們可以從dp[m]+1步來到達,所以轉移公式就是這麽來的
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; int a[N]; pair<ll,ll> maxx[N<<2]; ll dp[N]; void pushup(int rt) { if(maxx[rt<<1].fi>maxx[rt<<1|1].fi) maxx[rt]=maxx[rt<<1]; else maxx[rt]=maxx[rt<<1|1]; } void build(int l,int r,int rt) { if(l==r) { maxx[rt].fi=a[l]; maxx[rt].se=l; return ; } int m=(l+r)>>1; build(ls);build(rs); pushup(rt); } pair<ll,ll> query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return maxx[rt]; pair<ll,ll> ans,te; ans.fi=0; int m=(l+r)>>1; if(L<=m) { te=query(L,R,ls); if(ans.fi<te.fi)ans=te; } if(m<R) { te=query(L,R,rs); if(ans.fi<te.fi)ans=te; } return ans; } int main() { int n; scanf("%d",&n); for(int i=1;i<n;i++)scanf("%d",&a[i]); a[n]=n; build(1,n,1); // for(int i=1;i<n;i++)cout<<query(i+1,a[i],1,n,1).se<<" "; // cout<<endl; dp[n]=0; for(int i=n-1;i>=1;i--) { int te=query(i+1,a[i],1,n,1).se; // printf("%d\n",te); dp[i]=dp[te]+n-i-(a[i]-te); } ll ans=0; for(int i=1;i<=n;i++) { // printf("%d ",dp[i]); ans+=dp[i]; } printf("%lld\n",ans); return 0; } /******************** ********************/E
Codeforces Round #353 (Div. 2)