首页 > 其他分享 >Educational Codeforces Round 151 (Rated for Div. 2)(C,D)

Educational Codeforces Round 151 (Rated for Div. 2)(C,D)

时间:2023-06-30 18:44:27浏览次数:40  
标签:151 Educational Rated int sum long maxn include define

Educational Codeforces Round 151 (Rated for Div. 2)(C,D)

C(dp,子序列自动机)

C

题目大意就就是给你一个字符串\(s\),还给出两个边界字符串\(l\)和\(r\),长度为\(m\),问我们是否可以构造满足一下条件的字符串

\(1\),第\(i\)个字符必须在\(l_i\)和\(r_i\)的双闭区间里面

\(2\),这个获得的字符串不可以是\(s\)的序列(\(s\)里面删除任意个字符得到的字符串)

这一场我是\(vp\)的,结果惨不忍睹,但是,这个题我在\(vp\)时有思路,后面虽然时间过了,但是还是过了

既然是求不是\(s\)的子序列,我当时是求出以\(s\)的子序列,满足\(l,r\)要求的数量的字符串的数量(每一个位置可以是不同的字符),我们可以求出所有的数量,然后拿我们求得这个序列得到的字符串的数量,如果数量比所有的数量少,那么一定存在满足以上条件,否则,不满足

然后我就想出来状态转移方程

\[dp[i][j]=sum[i-1];\\sum[i]=\sum_{j=1}^{j=9}dp[i][j] \]

\(dp[i] [j]\)代表第\(i\)个字符是\(j\)的数量,\(sum[i]\)是\(dp[i]\)的\(1-9\)的和

但是我后面发现第\(i\)个字符为\(j\)可以存在\(s\)的多个不同位置,但是第\(i\)个字符为\(j\)的贡献只有\(1\),然后我每次得到一个最新的第\(i\)个字符为\(j\),我都会减去前面的值,然后再加上此时获得的值(一定大于等于前面的值),这样第\(i\)个字符为\(j\)的字符串数量一定是最大的数量

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
#include <bitset>
#include <numeric>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define eps 1e-6
#define mem(a,b) memset((a),(b),sizeof(a))
const int maxn=3e5+10;
const int mod=998244353;
int t;
int dp[maxn][10];
int sum[maxn];
int m,n;
string s,l,r;
void solve()
{
  cin>>s>>m>>l>>r;
  int cnt=1;
  n=s.size();
  s=" "+s;
  l=" "+l;
  r=" "+r;
  for (int i=1;i<=m;i++)
  {
    int tot=r[i]-l[i]+1;
    if(tot)
    {
      cnt=cnt*tot;
    }
    else 
    {
      cnt=0;
      break;
    }
    for (int j=0;j<=9;j++)
    {
      dp[i][j]=0;
    }
    sum[i]=0;
  }
  if(cnt==0)
  {
    cout<<"NO\n";
    return ;
  }
  for (int i=1;i<=n;i++)
  {
    int now=s[i]-'0';
    for (int j=m;j>=1;j--)
    {
      if(s[i]>=l[j]&&s[i]<=r[j])
      {
        int last=dp[j][now];
        if(j==1)
        {
          dp[j][now]=1;
        }
        else 
        {
          dp[j][now]=sum[j-1];
        }
        sum[j]-=last;
        sum[j]+=dp[j][now];
      }
    }
  }
  if(sum[m]>=cnt)
  {
    cout<<"NO\n";
  }
  else 
  {
    cout<<"YES\n";
  }
  return ;
}
signed main ()
{
  //ios;
  cin>>t;
  while (t--)
  {
    solve();
  }
  system ("pause");
  return 0;
}

然后我后面看到有大佬利用子序列自动机来解决这个问题

子序列自动机

这里使用子序列自动机来查找满足\(l,r\)条件的的字符串是否是\(s\)的子序列

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
#include <bitset>
#include <numeric>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define eps 1e-6
#define mem(a,b) memset((a),(b),sizeof(a))
const int maxn=3e5+10;
const int mod=998244353;
int t;
string s,l,r;
int n,m;
void solve()
{
  cin>>s;
  n=s.size();
  vector<vector<int>>nxt(n+2,vector<int>(10));
  for (int i=0;i<=9;i++)
  {
    nxt[n+1][i]=n+10;
  }
  s=" "+s;
  cin>>m>>l>>r;
  l=" "+l;
  r=" "+r;
  for (int i=n;i>=1;i--)
  {
    int now=s[i]-'0';
    nxt[i]=nxt[i+1];
    nxt[i][now]=i+1;
  }
  int last=1;
  for (int i=1;i<=m;i++)
  {
    int cur=0;
    int ll=l[i]-'0',rr=r[i]-'0';
    for (int j=ll;j<=rr;j++)
    {
      cur=max(cur,nxt[last][j]);
    }
    last=cur;
    if(last>n+1)
    {
      cout<<"YES\n";
      return ;
    }
  }
  cout<<"NO\n";
  return ;
}
signed main ()
{
  //ios;
  cin>>t;
  while (t--)
  {
    solve();
  }
  system ("pause");
  return 0;
}

D(思维)

D

这个题目的题意很好懂,大意就是给你一个长度为\(n\)的数组,每一个\(a_i\)都代表着一种变化(\(a_i\)可以小于\(0\)),把\(pre\)变成\(pre+a_i\),我们可以任意选择一个\(k\),这样后面要是遇到变化后如果\(pre\)小于\(k\)了,但是它可以不用变得那么小,而是直接变成\(k\),我们需要知道选择\(k\)为多少时,在经过\(n\)次变化之后得到的数最大

我们要让这个数最大,主要是靠那些变小的\(a_i\),我们可以把某一个在当前可以为最大的\(pre\)作为\(k\),然后后面我们要让这个\(k\)减小负数对\(pre\)的影响,那么就是\(premax\)和\(sum[i]\)(一切正常到了这个操作后的数字),让这两个数字之间的差值越大,那么主观下来,好像,可以让这些负数的操作使\(pre\)变小的数值更小

以上只是个人拙见

大佬题解

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
#include <bitset>
#include <numeric>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define eps 1e-6
#define mem(a,b) memset((a),(b),sizeof(a))
const int maxn=3e5+10;
const int mod=998244353;
int t;
int n,a[maxn],sum[maxn];
void solve()
{
  cin>>n;
  int ans=0;
  for (int i=1;i<=n;i++)
  {
    cin>>a[i];
    sum[i]=sum[i-1]+a[i];
  }
  int premax=0;
  int flag=0;
  for (int i=1;i<=n;i++)
  {
    if(sum[i]-premax<flag)
    {
      flag=sum[i]-premax;
      ans=premax;
    }
    premax=max(premax,sum[i]);
  }
  cout<<ans<<"\n";
  return ;
}
signed main ()
{
  //ios;
  cin>>t;
  while (t--)
  {
    solve();
  }
  system ("pause");
  return 0;
}

还发现了一个大佬的一个题解

标签:151,Educational,Rated,int,sum,long,maxn,include,define
From: https://www.cnblogs.com/righting/p/17517595.html

相关文章

  • Educational Codeforces Round 151 (Rated for Div. 2) A~D
     A.ForbiddenInteger模拟:voidsolve(){intn,k,x;cin>>n>>k>>x;if(x!=1){cout<<"YES\n"<<n<<"\n";for(inti=1;i<=n;i++)cout<<"1"<<"\n"......
  • Educational Codeforces Round 151 (Rated for Div
    C.StrongPassword给定一个字符串\(s\),一个密码的长度\(m\),下界字符串\(l\)和上界字符串\(r\),上下界字符串长度均为\(m\),且字符只在0~9范围内,上界字符串的第\(i\)位非严格大于下界字符串的第\(i\)位,密码的第\(i\)位需要位于\([l_i,r_i]\)内。问是否存在一个密码不是\(......
  • CodeTON Round 5 (Div. 1 + Div. 2, Rated, Prizes!) D. Tenzing and His Animal Fri
    题面是真的抽象,翻译为人话之后大概就是,对于每个选择的集合当中,1必须选,n一定不能选,每个限制条件的意思是如果u和v不在一个集合里则最能玩y时间,则u或v独自玩最多玩y时间如果在同一集合则可以玩无限时间因此如果n和1不连通的话则一定为inf,否则的话就一定有限制,因为n一定不能选,则和......
  • CodeTON Round 5 (Div. 1 + Div. 2, Rated, Prizes!) C. Tenzing and Balls
    一开始以为是贪心,后来发现不好贪于是选择了dp,但是dp有个小细节没注意到,后面wa了几发我们以状态来分,f[i]表示考虑i的最大区间合长度,每次转移的时候考虑两种情况,一种是a[i]前面有一样的数字,比较选了a[i]和不选a[i]两种情况下的最大值,还有一种就是a[i]为第一个出现的数字则选区间长......
  • Educational Codeforces Round 150 (Rated for Div. 2) A-E
    比赛链接A代码#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;boolsolve(){intn;cin>>n;if(n<=4)cout<<"Bob"<<'\n';elsecout<<"Alice"<<......
  • Automatic quality of generated text Evaluation for Large Language Models,针对大模
    一、LLM生成结果自动化评测的技术挑战和研发背景LargeLanguageModels(LLMs)haverecentlygrownrapidlyandtheyhavethepotentialtoleadtheAItransformation.ItiscriticaltoevaluateLLMsaccuratelybecause: Highqualityrequirementsforgenerativere......
  • 论文阅读 | Soteria: Provable Defense against Privacy Leakage in Federated Learni
    Soteria:基于表示的联邦学习中可证明的隐私泄露防御https://ieeexplore.ieee.org/document/95781923FL隐私泄露的根本原因3.1FL中的表示层信息泄露问题设置在FL中,有多个设备和一个中央服务器。服务器协调FL进程,其中每个参与设备仅与服务器通信本地模型参数,同时保持其本地......
  • CF1515G Phoenix and Odometers
    有点神仙的。题意给定一张\(n\)个点\(m\)条边的有向图,有边权,进行\(q\)次询问(\(n,m,q\le2\times10^5\),边权为不超过\(10^9\)的正整数)。每次询问给定三个参数\(v,s,t(0\les<t\le10^9)\),你需要回答是否存在一条起点终点均为\(v\)的路径,满足\(\text{路径长}+s\equi......
  • Educational Codeforces Round 82 (Rated for Div. 2)_A. Erasing Zeroes(C++_模拟)
    Youaregivenastring.Eachcharacteriseither0or1.Youwantall1’sinthestringtoformacontiguoussubsegment.Forexample,ifthestringis0,1,00111or01111100,thenall1’sformacontiguoussubsegment,andifthestringis0101,100001o......
  • 题解:【AT Educational DP Contest-O】 Matching
    题目链接来点位运算优化,目前也是拿下了洛谷最优解,比第二名快一倍:#include<bits/stdc++.h>#defineintlonglong#definebtp(x)__builtin_popcount(x)#definelowbit(x)((x)&(-x))usingnamespacestd;namespaceFastIO{template<typenameT=int>inlineTread()......