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 }
View Code

 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 }
View Code

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\n",k);
38         for(int i=0;i<Ans.size();++i)printf("%d%c",Ans[i],(i==k-1)?'\n':' ');
39     }
40 }
View Code

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 }
View Code

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 }
View Code

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\n",dp[n]);
89 }
View Code

猜你喜欢

转载自www.cnblogs.com/uuzlove/p/11961157.html
今日推荐