codeforces #603 (div 2) 做题记录
Posted uuzlove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces #603 (div 2) 做题记录相关的知识,希望对你有一定的参考价值。
A.
最少的那个一定用光,因此我们枚举最少的那个和另外两个配对分别用(a)和(b)
那么设另外两个是(x)和(y)
那么答案就是(a+b+min{(x-a,y-b)})
发现这个(min{x-a,y-b})是两段单调函数
那么我们二分这个最值点(分界点)就行了
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define pii pair<int,int> 5 #define pll pair<long long,long long> 6 #define mpr(a,b) make_pair(a,b) 7 using namespace std; 8 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);} 9 ll fastpow(ll a,ll p,ll mod) 10 { 11 ll ans=1; 12 while(p) 13 { 14 if(p&1)ans=ans*a%mod; 15 a=a*a%mod;p>>=1; 16 } 17 return ans; 18 } 19 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 20 int T; 21 int a[4]; 22 int main() 23 { 24 cin>>T; 25 while(T--) 26 { 27 cin>>a[1]>>a[2]>>a[3]; 28 sort(a+1,a+4); 29 int l=0,r=a[1],ans=0; 30 while(l<=r) 31 { 32 int mid=(l+r)>>1; 33 if(a[2]-mid>=a[3]-(a[1]-mid))ans=mid,l=mid+1; 34 else r=mid-1; 35 } 36 cout<<a[1]+min(a[2]-ans,a[3]-(a[1]-ans))<<endl; 37 } 38 }
B.
因为最多10个,那么我们就算都相同也可以把同一位改成0~9
然后就贪一下就行了
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define pii pair<int,int> 5 #define pll pair<long long,long long> 6 #define mpr(a,b) make_pair(a,b) 7 using namespace std; 8 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);} 9 ll fastpow(ll a,ll p,ll mod) 10 { 11 ll ans=1; 12 while(p) 13 { 14 if(p&1)ans=ans*a%mod; 15 a=a*a%mod;p>>=1; 16 } 17 return ans; 18 } 19 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 20 int T,n; 21 string s[11]; 22 int main() 23 { 24 cin>>T; 25 while(T--) 26 { 27 cin>>n; 28 for(int i=1;i<=n;++i)cin>>s[i]; 29 int ans=0; 30 for(int i=1;i<=n;++i) 31 { 32 bool yes=0; 33 for(int j=1;j<i;++j)if(s[i]==s[j])yes=1; 34 if(!yes)continue; 35 string tmp=s[i]; 36 ans++; 37 for(int k=0;k<=9;++k) 38 { 39 tmp[0]=k+‘0‘; 40 int tot=0; 41 for(int j=1;j<=n;++j)if(j!=i)if(tmp==s[j])tot++; 42 if(!tot)break; 43 } 44 s[i]=tmp; 45 } 46 cout<<ans<<endl; 47 for(int i=1;i<=n;++i)cout<<s[i]<<endl; 48 } 49 }
C.
数论分块裸题
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define pii pair<int,int> 5 #define pll pair<long long,long long> 6 #define mpr(a,b) make_pair(a,b) 7 using namespace std; 8 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);} 9 ll fastpow(ll a,ll p,ll mod) 10 { 11 ll ans=1; 12 while(p) 13 { 14 if(p&1)ans=ans*a%mod; 15 a=a*a%mod;p>>=1; 16 } 17 return ans; 18 } 19 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 20 int T,n; 21 int main() 22 { 23 cin>>T; 24 while(T--) 25 { 26 cin>>n; 27 vector<int> Ans; 28 Ans.clear(); 29 Ans.push_back(0); 30 for(int i=1;i<=n;++i) 31 { 32 Ans.push_back(n/i); 33 i=n/(n/i); 34 } 35 sort(Ans.begin(),Ans.end()); 36 int k=Ans.size(); 37 printf("%d ",k); 38 for(int i=0;i<Ans.size();++i)printf("%d%c",Ans[i],(i==k-1)?‘ ‘:‘ ‘); 39 } 40 }
D.
并查集维护字母集合
每种字母得判一下出没出现
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define pii pair<int,int> 5 #define pll pair<long long,long long> 6 #define mpr(a,b) make_pair(a,b) 7 using namespace std; 8 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);} 9 ll fastpow(ll a,ll p,ll mod) 10 { 11 ll ans=1; 12 while(p) 13 { 14 if(p&1)ans=ans*a%mod; 15 a=a*a%mod;p>>=1; 16 } 17 return ans; 18 } 19 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 20 int n; 21 char s[1000005]; 22 int fa[27],cnt[27],tmp[27]; 23 int find(int x) 24 { 25 if(fa[x]==x)return fa[x]; 26 return fa[x]=find(fa[x]); 27 } 28 int main() 29 { 30 scanf("%d",&n); 31 for(int i=1;i<=26;++i)fa[i]=i; 32 for(int i=1;i<=n;++i) 33 { 34 scanf("%s",s+1); 35 int len=strlen(s+1); 36 memset(tmp,0,sizeof(tmp)); 37 for(int j=1;j<=len;++j)cnt[s[j]-‘a‘+1]++,tmp[s[j]-‘a‘+1]++; 38 for(int j=1;j<=26;++j) 39 for(int k=1;k<=26;++k)if(tmp[j]&&tmp[k]&&find(j)!=find(k))fa[find(j)]=find(k); 40 } 41 int ans=0; 42 for(int i=1;i<=26;++i)if(find(i)==i&&cnt[i])ans++; 43 cout<<ans<<endl; 44 }
E.
考虑把左括号当成从(pos)到(end)的后缀加,右括号看成后缀减
那么合法序列等价于全局最小大于等于0,然后(end)权值为0
最深括号嵌套深度等于全局最大值
这个可以线段树维护
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define pii pair<int,int> 5 #define pll pair<long long,long long> 6 #define mpr(a,b) make_pair(a,b) 7 using namespace std; 8 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);} 9 ll fastpow(ll a,ll p,ll mod) 10 { 11 ll ans=1; 12 while(p) 13 { 14 if(p&1)ans=ans*a%mod; 15 a=a*a%mod;p>>=1; 16 } 17 return ans; 18 } 19 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 20 #define maxn 2000005 21 int n; 22 char opt[maxn],s[maxn]; 23 int pos; 24 int addv[maxn<<2],maxv[maxn<<2],minv[maxn<<2]; 25 void pushup(int rt) 26 { 27 maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]); 28 minv[rt]=min(minv[rt<<1],minv[rt<<1|1]); 29 } 30 void pushdown(int rt) 31 { 32 if(addv[rt]) 33 { 34 int t=addv[rt]; 35 maxv[rt<<1]+=t;maxv[rt<<1|1]+=t; 36 minv[rt<<1]+=t;minv[rt<<1|1]+=t; 37 addv[rt<<1]+=t;addv[rt<<1|1]+=t; 38 addv[rt]=0; 39 } 40 } 41 void add(int rt,int l,int r,int ql,int qr,int v) 42 { 43 if(ql<=l&&r<=qr) 44 { 45 maxv[rt]+=v;minv[rt]+=v; 46 addv[rt]+=v; 47 return; 48 } 49 pushdown(rt); 50 int mid=(l+r)>>1; 51 if(ql<=mid)add(rt<<1,l,mid,ql,qr,v); 52 if(qr>mid)add(rt<<1|1,mid+1,r,ql,qr,v); 53 pushup(rt); 54 } 55 int querymax(int rt,int l,int r,int ql,int qr) 56 { 57 if(ql<=l&&r<=qr)return maxv[rt]; 58 pushdown(rt); 59 int ans=0,mid=(l+r)>>1; 60 if(ql<=mid)ans=max(ans,querymax(rt<<1,l,mid,ql,qr)); 61 if(qr>mid)ans=max(ans,querymax(rt<<1|1,mid+1,r,ql,qr)); 62 pushup(rt); 63 return ans; 64 } 65 int querymin(int rt,int l,int r,int ql,int qr) 66 { 67 if(ql<=l&&r<=qr)return minv[rt]; 68 pushdown(rt); 69 int ans=0,mid=(l+r)>>1; 70 if(ql<=mid)ans=min(ans,querymin(rt<<1,l,mid,ql,qr)); 71 if(qr>mid)ans=min(ans,querymin(rt<<1|1,mid+1,r,ql,qr)); 72 pushup(rt); 73 return ans; 74 } 75 int main() 76 { 77 scanf("%d",&n); 78 scanf("%s",opt+1); 79 pos=1; 80 int M=1000002; 81 for(int i=1;i<=n;++i) 82 { 83 if(opt[i]==‘L‘)pos=max(1,pos-1); 84 else if(opt[i]==‘R‘)pos++; 85 else 86 { 87 if(s[pos]==‘(‘)add(1,1,M,pos,M,-1); 88 if(s[pos]==‘)‘)add(1,1,M,pos,M,1); 89 s[pos]=opt[i]; 90 if(s[pos]==‘(‘)add(1,1,M,pos,M,1); 91 if(s[pos]==‘)‘)add(1,1,M,pos,M,-1); 92 } 93 if(querymax(1,1,M,M,M)!=0||querymin(1,1,M,1,M)<0)printf("%d ",-1); 94 else printf("%d ",querymax(1,1,M,1,M)); 95 } 96 }
F.
考虑我们一棵子树里的边一定是都选(否则不连通没有意义)
然后我们就可以把子树表示的区间搞出来,然后DP一下就行了
(dp[r]=max{(dp[l-1]+subtree(l,r))})
状态(O(n)),总转移数(O(n))
复杂度(O(n))
1 #include<bits/stdc++.h> 2 #define maxn 2005 3 #define ll long long 4 #define ull unsigned long long 5 #define pii pair<int,int> 6 #define pll pair<long long,long long> 7 #define mpr(a,b) make_pair(a,b) 8 using namespace std; 9 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);} 10 ll fastpow(ll a,ll p,ll mod) 11 { 12 ll ans=1; 13 while(p) 14 { 15 if(p&1)ans=ans*a%mod; 16 a=a*a%mod;p>>=1; 17 } 18 return ans; 19 } 20 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 21 int n,a,b; 22 int sum[maxn][maxn]; 23 vector<int> ga[maxn],gb[maxn]; 24 int ax[maxn],by[maxn],xa[maxn],yb[maxn]; 25 int amx[maxn],amn[maxn],bmx[maxn],bmn[maxn]; 26 int sza[maxn],szb[maxn]; 27 vector<pii> av[maxn],bv[maxn]; 28 void dfs1(int u) 29 { 30 sza[u]=1; 31 if(xa[u])amn[u]=amx[u]=xa[u]; 32 else amn[u]=2001,amx[u]=0; 33 for(int v:ga[u]) 34 { 35 dfs1(v); 36 amn[u]=min(amn[u],amn[v]); 37 amx[u]=max(amx[u],amx[v]); 38 sza[u]+=sza[v]; 39 } 40 av[amx[u]].push_back(mpr(amn[u],(u==1)?sza[u]-1:sza[u])); 41 } 42 void dfs2(int u) 43 { 44 szb[u]=1; 45 if(yb[u])bmn[u]=bmx[u]=yb[u]; 46 else bmn[u]=2001,bmx[u]=0; 47 for(int v:gb[u]) 48 { 49 dfs2(v); 50 bmn[u]=min(bmn[u],bmn[v]); 51 bmx[u]=max(bmx[u],bmx[v]); 52 szb[u]+=szb[v]; 53 } 54 bv[bmx[u]].push_back(mpr(bmn[u],(u==1)?szb[u]-1:szb[u])); 55 } 56 int dp[maxn]; 57 int main() 58 { 59 scanf("%d",&n); 60 scanf("%d",&a); 61 for(int x,i=2;i<=a;++i) 62 { 63 scanf("%d",&x); 64 ga[x].push_back(i); 65 } 66 for(int i=1;i<=n;++i)scanf("%d",&ax[i]),xa[ax[i]]=i; 67 scanf("%d",&b); 68 for(int x,i=2;i<=b;++i) 69 { 70 scanf("%d",&x); 71 gb[x].push_back(i); 72 } 73 for(int i=1;i<=n;++i)scanf("%d",&by[i]),yb[by[i]]=i; 74 dfs1(1);dfs2(1); 75 for(int i=1;i<=n;++i) 76 { 77 for(pii u:av[i]) 78 { 79 int j=u.first,w=u.second; 80 dp[i]=max(dp[i],dp[j-1]+w); 81 } 82 for(pii u:bv[i]) 83 { 84 int j=u.first,w=u.second; 85 dp[i]=max(dp[i],dp[j-1]+w); 86 } 87 } 88 printf("%d ",dp[n]); 89 }
以上是关于codeforces #603 (div 2) 做题记录的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #603 (Div. 2) E. Editor(线段树)
Codeforces Round #603 (Div. 2)
Codeforces Round #603 (Div. 2)
Codeforces Round #603 (Div. 2) E. Editor 线段树