首页 > 其他分享 >Codeforces Round #773 (Div. 2)

Codeforces Round #773 (Div. 2)

时间:2022-08-24 14:46:52浏览次数:95  
标签:cnt 773 int cin Codeforces mp 区间 Div define

Codeforces Round #773 (Div. 2)

VP

A B C
24min 31min 48min
+2 +1

A

\(\color{Gray}{800}\)

CF1642A Hard Way

观察题目样例外加手摸可知,只有满足三角形中某条边与 \(x\) 轴平行且在最上面的情况下,有且仅有这条边算作贡献。
稍加模拟即可。

时间复杂度:\(O(1)\)

#define pi pair <int,int>
#define F(i) (i).first
#define S(i) (i).second
pi a[4];
void work(){
  for(int i=1;i<=3;i++) cin>>F(a[i])>>S(a[i]);
  if(S(a[2])==S(a[1])&&S(a[3])<S(a[1])) return cout<<abs(F(a[2])-F(a[1]))<<'\n',void();
  if(S(a[2])==S(a[3])&&S(a[1])<S(a[2])) return cout<<abs(F(a[3])-F(a[2]))<<'\n',void();
  if(S(a[3])==S(a[1])&&S(a[2])<S(a[1])) return cout<<abs(F(a[3])-F(a[1]))<<'\n',void();
  cout<<0<<'\n';
}

B

\(\color{Gray}{900}\)

CF1642B Power Walking

从后向前考虑,先分成 \(n\) 组后合并。
不难发现,重复的数字个数 \(x\) 即前 \(x\) 次合并能减小贡献 \(1\) 的情况。
使用 std::sort()std::unique() 模拟过程即可。

时间复杂度:\(O(n \log_2 n)\)

#define L(i,j,k) for(int i=(j);i<=(k);i++)
int n,cnt;
const int N=3e5+10;
int a[N],ans[N];
void work(){
  cin>>n;L(i,1,n) cin>>a[i];
  sort(a+1,a+1+n);
  cnt=unique(a+1,a+1+n)-a-1;
  cnt=n-cnt;int x=n;
  R(i,n,1){
    ans[i]=x;
    if(cnt) x--,cnt--;
  }L(i,1,n) cout<<ans[i]<<' ';
  cout<<'\n';
}

C

\(\color{ForestGreen}{1200}\)

CF1641A Great Sequence

不难想到,每次操作能解决一个没有配对的数。
std::map 统计一下就行了。
不知道为啥 std::unordered_map 这回没被针对

时间复杂度:\(O(n \log_2 n)\)

#define L(i,j,k) for(int i=(j);i<=(k);i++)
int n,k,cnt;
map<int,int>mp;
const int N=3e5+10;
int a[N];
void work(){
  mp.clear();cnt=0;
  cin>>n>>k;L(i,1,n) cin>>a[i],mp[a[i]]++;
  sort(a+1,a+1+n);
  L(i,1,n) if(mp[a[i]*k]&&mp[a[i]]) 
    mp[a[i]]--,mp[a[i]*k]--;
  L(i,1,n) cnt+=mp[a[i]],mp[a[i]]=0;
  cout<<cnt<<'\n';
}

D

\(\color{Purple}{2000}\)
这 CD gap 咋这么大

CF1641B Repetitions Decoding

题目把操作次数给的非常充裕,所以考虑比较暴力的想法。
对于某个数 \(a_i\),找到第一个与之相等的数 \(a_j\)。
然后将 \(a_k \left( k \in \left[ i+1,j-1 \right] \right)\) 的数按顺序加入。

比如:\(12341\)
\(12341 \mapsto 1234122 \mapsto 123412332 \mapsto 1234234432\)
去掉可以作为答案序列的部分,得到 \(432\)。

每次进行操作,相当于去掉头尾的数,将中间序列翻转。

模拟此过程即可,最多进行 \(O(\dfrac{n^2}{2})\) 次,可以通过。

时间复杂度:\(O(n^3)\)

#define F(i) (i).first
#define S(i) (i).second
#define pb push_back
#define pi pair<int,int>
#define L(i,j,k) for(int i=(j);i<=(k);i++)
void work(){
  vector<int>a,l;vector<pi>ans;
  map<int,int>mp;int x,n,len=0;
  cin>>n;L(i,0,n-1) 
    cin>>x,a.pb(x),mp[x]++;
  for(int i:a) if(mp[i]&1) 
    return cout<<-1<<'\n',void();
  while(!a.empty()){
    L(j,1,a.size()-1)
      if(a[0]==a[j]){
        L(k,0,j-2) ans.pb({len+k+1+j,a[k+1]});
        l.pb(j*2);len+=j*2;
        reverse(a.begin()+1,a.begin()+j);
        a.erase(a.begin()+j),a.erase(a.begin());
        break;
      }
  }cout<<ans.size()<<'\n';
  for(auto x:ans) 
    cout<<F(x)<<' '<<S(x)<<'\n';
  cout<<l.size()<<'\n';
  for(int i:l) 
    cout<<i<<' ';cout<<'\n';
}

E

\(\color{Orange}{2200}\)

CF1641C Anonymity Is Important

用 \(0\) 区间和 \(1\) 区间描述题目中的区间。
对题意进行分析:

  • 如果某人在 \(0\) 区间内,则必定不是。
  • 如果某人在 \(1\) 区间内,且此 \(1\) 区间中其余人都被前一条确定否,则必定是,否则不确定。

比如

11000010001111
   -  ^  -

^ 指向的是当前询问对象,当且仅当其本身和其左右 0 的连续段 中包含这个 \(1\) 区间,才能确定其为病人。

考虑用 std::set 维护这些信息。一开始将所有点丢到 std::set 里,确认不为病人后踢出即可。
询问时先找到中间那一位的前驱 \(l\) 后继 \(r\) 。
如果存在左端点在 \(( l,x ]\),右端点在 \([ x,r )\) 的 \(1\) 区间,就能确定此人为病人。

  • 线段树:

如果用线段树维护,就是单点修改,区间查询,维护区间最小值
每次输入 \(1\) 区间时将 $\text{seg_tree}_ l $ 赋值为 \(\min(\text{seg_tree}_ l,r)\) 即可。
每次询问判断 \(ask(l+1,x)\) 与 \(r\) 的关系即可。

时间复杂度:\(O(n\log_2 n)\)

#define L(i,j,k) for(int i=(j);i<=(k);i++)
int n,q;set<int>st;
const int N=2e5+100,INF=1e9;
struct tree{int l,r,z;}s[N<<2];
void pushup(int p){s[p].z=min(s[lc].z,s[rc].z);}
void build(int p,int l,int r){
  s[p]=(tree){l,r,INF};
  if(l==r) return;int m=(l+r)>>1;
  build(lc,l,m);build(rc,m+1,r);
}void change(int x,int k,int p=1){
  s[p].z=min(s[p].z,k);
  if(s[p].l==s[p].r) return ;
  int m=(s[p].l+s[p].r)>>1;
  change(x,k,(x<=m?lc:rc));
  pushup(p);
}int ask(int l,int r,int p=1){
  if(s[p].l>=l&&s[p].r<=r) return s[p].z;
  int m=(s[p].l+s[p].r)>>1,v=INF;
  if(l<=m) v=min(v,ask(l,r,lc));
  if(r>m) v=min(v,ask(l,r,rc));
  return v;
}void work(){
  cin>>n>>q;
  build(1,0,n+1);
  L(i,0,n+1) st.insert(i);
  while(q--){
    int o;cin>>o;
    if(o){
      int j;cin>>j;
      auto i=st.lower_bound(j);
      if(*i!=j) cout<<"NO"<<'\n';
      else{
        auto k=i--;k++;
        cout<<((*k>(ask(*i+1,j)))?"YES":"N/A")<<'\n';
      }
    }else{
      int l,r,x;
      cin>>l>>r>>x;
      if(x) change(l,r);
      else{
        auto a=st.lower_bound(l),b=st.upper_bound(r);
        while(a!=b){auto c=a++;st.erase(c);}
      }
    }
  }
}
  • 并查集:

考虑使用并查集维护连通块。对于一个 \(0\) 区间 \([l,r]\),可以在并查集中把 \([l,r+1]\) 合并,同时将 \(r+1\) 作集合代表元素,把编号小者合并到编号大者集合内。
同时维护 \(\forall i \in [l,r+1]\),若 \(i\) 为一个 \(0\) 区间的左端点,则右端点的最小值,此值在连通块最右端(集合代表元素)处更新。

然后对 \(i\) 是否有病进行判断:
若无病,则其一定非集合代表元素。
若有病,则其一定是集合代表元素,且包括与其同一集合的元素右端点最小值一定小于其右边连通块代表元素。
(也就是有包括他的有病者所在的区间,且区间内此人之前和之后的人全部没有病)。
(若不小于,则证明没有满足上述要求的区间,此人不能明确是否患病)。

时间复杂度:\(O(n\alpha(n))\)

int n,q,a,b;
const int N=2e5+100,INF=1e9;
int f[N],g[N];
int cz(int x){return x==f[x]?x:f[x]=cz(f[x]);}
void work(){
  cin>>n>>q;++n;
  L(i,1,n) f[i]=i,g[i]=INF;
  while(q--){
    int o,l,r;
    cin>>o>>l;
    if(o){
      if(cz(l)!=l) cout<<"NO"<<'\n';
      else
        if(g[l]<cz(l+1)) cout<<"YES"<<'\n';
        else cout<<"N/A"<<'\n';
    }else{
      cin>>r>>o;
      if(o)
        a=cz(l),g[a]=min(g[a],r);
      else
        while(l<=r){
          a=cz(l);b=cz(l+1);f[a]=b;
          g[b]=min(g[a],g[b]);l=b;
        }
    }
  }
}

标签:cnt,773,int,cin,Codeforces,mp,区间,Div,define
From: https://www.cnblogs.com/AIskeleton/p/16619817.html

相关文章

  • Codeforces Round #815 (Div. 2) E. Misha and Paintings
    人生中第一个AC的codeforces题,大概太难了,光是看答案就看了整整一下午,最后还是在b站上搜到讲解视频才明白的。俺们阿B真的是太厉害啦这道题首先容易看出当矩阵中数字个数......
  • Codeforces Round #783 (Div. 2) E (证明+构造)
    一般这种题我们都是先推导下界再来构造那我们假设我们当前放置了k位半皇后我们只考虑横竖被吃掉并且贪心的(类似于八皇后的选择)横竖都不重叠我们把他固定在左上角的kk......
  • Codeforces Round #292 (Div. 2) C. Drazil and Factorial(思维)
    https://codeforces.com/contest/515题目大意:给我们一个长度为n的数字a定义F(a)=a里面每一位数的阶层总乘积让我们求最大的x,需要满足F(x)=f(a)并且x中没有0和1input4......
  • Codeforces Round #638 (Div. 2) B. Phoenix and Beauty(构造/思维)
    https://codeforces.com/contest/1348/problem/B如果一个数组的所有长度为k的子数组的和相同,那么这个数组就是美丽的。数组的子数组是任何连续元素的序列。Phoenix目前......
  • *Codeforces Round #363 (Div. 1) A. Vacations(状态机)
    https://codeforces.com/contest/698/problem/AVasya有n天假期!Vasya知道关于这n天中每一天的以下信息:那家健身房是否开门,以及那天是否在互联网中进行了比赛。第i天有四个......
  • CodeForces-1715D 2+ doors
    2+doors贪心位与位之间互不一向,因此考虑每个位进行考虑就行因为是或的关系,先考虑\(0\)的情况,如果出现\(0\),则两个数字的该位必然是\(0\)如果是\(1\)的情况,就考......
  • CodeForces-1715C Monoblock
    Monoblockdp先想想如何计算初始值\(dp[x]\)表示以第\(x\)个位置为\(r\),他的所有贡献状态转移:如果\(a_x=a_{x-1}\):\(dp[x]=dp[x-1]+1\),代表只增加了\(l......
  • CodeForces-1719D Burenka and Traditions
    BurenkaandTraditions贪心由于代价是向上取整的,因此可以直接考虑成两种方式:选择两个相邻的数,让他们同时异或上一个值选择一个数字,让他变成\(0\)由此可见,最多......
  • Codeforces Round #743 (Div. 2) B. Swaps(思维)
    https://codeforces.com/contest/1573/problem/B给定两个长度为n的数组,数组a和数组b数组a包含从1到2*n的任意顺序的奇数,数组b包含从1到2*n的任意偶数可执行的操作如下:......
  • Codeforces 1715E - Long Way Home
    又是废掉的一个div2啊第一次在学校熬夜打cf,开心还看到了自己最喜欢的斜率优化ohhh链接:E-LongWayHome看到那个平方就可以靠感觉认为是斜率优化了....感觉似不似......