首页 > 其他分享 >Educational Codeforces Round 23 A - F

Educational Codeforces Round 23 A - F

时间:2023-09-02 18:22:45浏览次数:41  
标签:Educational 23 int Codeforces mid seg tag stk id

Educational Codeforces Round 23

目录

A - Treasure Hunt

往四个方向走,每次操作会变动横坐标和纵坐标,横纵坐标的绝对值要能整除操作的改变量,同时横纵坐标的操作次数的奇偶性相同

void solve()
{       
    int a, b, c, d; cin>>a>>b>>c>>d;
    int t1 = abs(a - c);
    int t2 = abs(b - d);
    int x, y;   cin>>x>>y;
    if(t1 % x == 0 && t2 % y == 0 && abs(t1 / x) % 2 == abs(t2 / y) % 2)
        cout<<"YES\n";
    else 
        cout<<"NO\n";
 
    return;
}

B - Makes And The Product

分类讨论,预处理出 \(a_i, a_j, a_k\) 的下标

三种情况:

  1. \(a_i = a_j = a_k\) 答案为 \(\dfrac{cnt_{a_i} \times (cnt_{a_i} - 1) \times (cnt_{a_i} - 2)}{6}\)
  2. \(a_i = a_j \ne a_k\) 答案为 \(cnt_{a_k}\) ,\(a_i \ne a_j = a_k\) 答案为 \(cnt_{a_i} \times \dfrac{cnt_{a_k} \times (cnt_{a_k} - 1)}{2}\)
  3. \(a_i \ne a_j \ne a_k\) 答案为 \(cnt_{a_i} \times cnt_{a_j} \times cnt_{a_k}\)

代码写得有点乱

const int N = 2e5 + 10;
 
int n, a[N], b[N];
ll f[4];
void solve()
{       
    int x, y, z;
    cin>>n;
    for(int i = 1; i <= n; i++)
    {
        cin>>a[i];
        b[i] = a[i];
    }
    sort(b + 1, b + 1 + n);
    x = b[1], y = b[2], z = b[3];
    vector<int> c, e[5];
    c.push_back(x), c.push_back(y), c.push_back(z);
    c.erase(unique(c.begin(), c.end()), c.end());
    for(int i = 1; i <= n; i++)
        for(int j = 0; j < c.size(); j++)
            if(a[i] == c[j])
                f[j]++;
 
    if(f[2] != 0)
    {
        cout<<f[0] * f[1] * f[2]<<'\n';
        return;
    }
    else if(f[1] != 0)
    {
        if(f[0] == 2)
        {
            cout<<f[0] / 2 * f[1]<<'\n';
        }
        else
            cout<<f[0] * f[1] * (f[1] - 1) / 2<<'\n';
 
    }
    else
        cout<<f[0] * (f[0] - 1) * (f[0] - 2) / 6<<'\n';
 
    return;
}

C - Really Big Numbers

若 \(mid = a_1 \times 10^x + a_2 \times 10^{x-1} + \dots + a_n \times 10^0 - 9 \times x \geq s\)

那么 \([mid, n]\) 的数都满足要求

我们只要暴力判断 \([s, mid]\) 这个区间的数即可

所以二分出 \(mid\),再暴力判断即可,因为最大减去的数位和是 \(18 \times 9\) ,所以最多暴力这么点数就可以了

特判 \(mid\) 不满足要求的情况

typedef long long ll;

ll n, s;
 
bool check(ll x)
{
    ll t = x;
    ll sub = 0;
    while(t)
    {
        t /= 10;
        sub += 9;
    }
    if(x - sub >= s)
        return true;
    else return false;
}
void solve()
{       
    cin>>n>>s;
    ll l = 1, r = n + 2;
    while(l < r)
    { 
        ll mid = (l + r) >> 1;
        if(check(mid))  r = mid;
        else l = mid + 1;
    }
    ll res = 0;
    if(l <= n && check(l))    res = n - l + 1;
    // cout<<l<<" "<<res<<'\n';
 
    // cout<<l<<" "<<res<<'\n';
    if(l > n)   l = n + 1;
    
    for(ll i = s; i <= l - 1; i++)
    {
        ll t = i;
        ll sub = 0;
        while(t)
        {
            sub = sub + (t % 10);
            t /= 10;
        }
        if(i - sub >= s)    res++;
 
    }
    cout<<res<<'\n';
 
    return;
}

D - Imbalanced Array

可以观察到:

  1. 每一个数字 \(a_i\) 都作为最小值,最大值分别存在一个或多个区间区间
  2. 再观察到 \(res = s2 - s1\), \(s1\) 作为所有区间的最小值之和, \(s2\) 作为所有区间的最大值之和
  3. 那么我们就需要预处理出每个数字的最小值,最大值的区间,我们就需要求出 \(a_i\) 从左往右第一个小于等于它的位置, 从右往左第一个小于它的位置,从左往右第一个大于等于它的位置, 从右往左第一个大于它的位置
  4. 发现可以用单调栈处理
typedef long long ll;
 
const int mod = 1e9 + 7;
const int N = 1e6 + 10;
 
 
ll s1, s2;
ll n, a[N];
ll f[N], g[N];
void solve()
{       
    stack<ll> stk; 
    cin>>n;
    for(int i = 1; i <= n; i++)
        cin>>a[i];
 
    for(int i = 1; i <= n; i++)
    {
        while(!stk.empty() && a[stk.top()] >= a[i]) stk.pop();
        if(stk.empty()) f[i] += i;
        else f[i] = i - stk.top();
        stk.push(i);
    }
    while(!stk.empty())
        stk.pop();
    for(int i = n; i >= 1; i--)
    {
        while(!stk.empty() && a[stk.top()] > a[i]) stk.pop();
        if(stk.empty()) f[i] *= (n - i + 1);
        else f[i] *= (stk.top() - i);
        stk.push(i);
    }   
 
 
    while(!stk.empty())
        stk.pop();
    for(int i = 1; i <= n; i++)
    {
        while(!stk.empty() && a[stk.top()] <= a[i]) stk.pop();
        if(stk.empty()) g[i] += i;
        else g[i] = i - stk.top();
        stk.push(i);
    }
    while(!stk.empty())
        stk.pop();
    for(int i = n; i >= 1; i--)
    {
        while(!stk.empty() && a[stk.top()] < a[i]) stk.pop();
        if(stk.empty()) g[i] *= (n - i + 1);
        else g[i] *= (stk.top() - i);
        stk.push(i);
    }   
 
 
    // for(int i = 1; i <= n; i++)
    //     cout<<f[i]<<"  ";
    // cout<<'\n';
 
    // for(int i = 1; i <= n; i++)
    //     cout<<g[i]<<"  ";
    // cout<<'\n';
    for(int i = 1; i <= n; i++)
    {
        s1 += (f[i] * a[i]);
        s2 += (g[i] * a[i]);
    }
    cout<<s2 - s1<<'\n';
    return;
}
 

E - Choosing The Commander

01 trie 板子

const int N = 2e5 + 10;
 
 
struct 
{
    int sz, s[2];
}seg[N * 32];
 
int root, tot = 0, q;
 
void insert(int x)
{
    int p = root;
    for(int j = 29; j >= 0; j--)
    {
        int w = (x >> j) & 1;
        seg[p].sz++;
        if(seg[p].s[w] == 0)  seg[p].s[w] = ++tot;
        p = seg[p].s[w];
    }
    seg[p].sz++;
}
void del(int x)
{
    int p = root;
    for(int j = 29; j >= 0; j--)
    {
        int w = (x >> j) & 1;
        seg[p].sz--;
        // if(seg[p].s[w] == 0)  seg[p].s[w] = ++tot;
        p = seg[p].s[w];
    }
    seg[p].sz--;
}
 
int query(int x, int k)
{
    int p = root;
    int ans = 0;
    for(int j = 29; j >= 0; j--)
    {
        int w = (x >> j) & 1; 
        int t = (k >> j) & 1;           
        if(w == 0 && t == 0)
        {
            p = seg[p].s[0];
        }
        else if(w == 0 && t == 1)
        {
            ans += seg[seg[p].s[0]].sz;
            p = seg[p].s[1];
        }
        else if(w == 1 && t == 0)
        {
            // ans += seg[seg[p].s[1]].sz;
            p = seg[p].s[1];
        }
        else if(w == 1 && t == 1)
        {
            ans += seg[seg[p].s[1]].sz;
            p = seg[p].s[0];            
        }
 
        // if(seg[seg[p].s[w]].sz >= k)
        //     p = seg[p].s[w];
        // else 
        // {
        //     k -= seg[seg[p].s[w]].sz;
        //     p = seg[p].s[1 ^ w];
        //     ans = ans ^ (1 << j);
        // }
    }
    return ans;
}
 
void solve()
{   
    cin>>q;
    root = ++tot;
    for(int i = 1; i <= q; i++)
    {
        int opt;    cin>>opt;
        if(opt == 1)
        {
            int x;  cin>>x;
            insert(x);
        }
        else if(opt == 2)
        {
            int x;  cin>>x;
            del(x);
        }
        else if(opt == 3)
        {
            int x, k;  cin>>x>>k;
            cout<<query(x, k)<<'\n';
        }
    }
    return;
}

F - MEX Queries

  • 维护一个集合,初始为空。
  • 有 \(3\) 种操作:

    1. 把 \([l,r]\) 中在集合中没有出现过的数添加到集合中。
    2. 把 \([l,r]\) 中在集合中出现过的数从集合中删掉。
    3. 把 \([l,r]\) 中在集合中没有出现过的数添加到集合中,并把 \([l,r]\) 中在集合中出现过的数从集合中删掉。
  • 每次操作后输出集合的 \(\operatorname{MEX}\) —— 在集合中没有出现过的最小正整数。

    how to:

    1. 每次要对 \([l, r]\) 集合处理,看上去很复杂,不难发现答案就是一段区间的断点,我们将询问离线,把 \(l - 1, l, r, r + 1\) 离散化处理

    2. 如何维护区间端点?建立一棵线段树,有对一段区间进行赋值 \(0/1\) 和取反操作

    3. 如何查询答案,线段树二分找区间的最左的 \(0\) ,就做完了

      //  AC one more times
       
      #include <bits/stdc++.h>
       
      using namespace std;
       
      typedef long long ll;
       
      const int mod = 1e9 + 7;
      const int N = 6e5 + 10;
      int n;
      vector<ll> vx;
      vector<array<ll, 3>> event;
      struct info
      {
          int val;
      };
       
      struct tag
      {
          int tag1, tag2;
      };
       
      info operator + (const info &a, const info &b)
      {
          info t;
          t.val = a.val + b.val;
          return t;
      }
       
      struct segtree
      {
          struct info val;
          struct tag tag;
          int sz;     // ...
      }seg[N * 4];
       
       
      void update(int id)
      {
          seg[id].val = seg[id * 2].val + seg[id * 2 + 1].val;
      }
       
      void settag(int id, struct tag tag)
      {
          if(tag.tag1 != 0)
          {
              if(tag.tag1 == 1)
              {
                  seg[id].val.val = seg[id].sz;
              }
              else if(tag.tag1 == 2)
              {
                  seg[id].val.val = 0;
              }
              seg[id].tag.tag1 = tag.tag1;
              seg[id].tag.tag2 = 0;
          }
          if(tag.tag2 != 0)
          {
              seg[id].val.val = seg[id].sz - seg[id].val.val;
              seg[id].tag.tag2 = seg[id].tag.tag2 ^ 1;
          }
      }
      void pushdown(int id)
      {
          if(seg[id].tag.tag1 != 0 || seg[id].tag.tag2 != 0)
          {
              settag(id * 2, seg[id].tag);
              settag(id * 2 + 1, seg[id].tag);
              seg[id].tag = {0, 0};
          }
      }
       
      void build(int id, int l, int r)
      {
          seg[id].sz = r - l + 1;
          seg[id].tag = {0, 0};
          if(l == r)
          {
              seg[id].val.val = 0;
              return;
          }
          int mid = (l + r) >> 1;
          build(id * 2, l, mid);
          build(id * 2 + 1, mid + 1, r);
          update(id);
      }
       
      void modify(int id, int l, int r, int ql, int qr, struct tag tag)
      {
          if(l == ql && r == qr)
          {
              settag(id, tag);
              return;
          }
          pushdown(id);
          int mid = (l + r) >> 1;
          if(qr <= mid)
              modify(id * 2, l, mid, ql, qr, tag);
          else if(ql > mid)
              modify(id * 2 + 1, mid + 1, r, ql, qr, tag);
          else 
              modify(id * 2, l, mid, ql, mid, tag),
              modify(id * 2 + 1, mid +1 , r, mid + 1, qr, tag);
          update(id);
      }
       
      int query(int id, int l, int r)
      {
          if(l == r)
              return l;
          pushdown(id);
          int mid = (l + r) >> 1;
          if(seg[id * 2].val.val != seg[id * 2].sz) 
              return query(id * 2, l, mid);
          else
              return query(id * 2 + 1, mid + 1, r);
      }
      void solve()
      {
          cin>>n;
          for(int i = 1; i <= n; i++)
          {
              ll a, b, c; cin>>a>>b>>c;
              if(b - 1 >= 1)
                  vx.push_back(b - 1);
              if(c - 1 >= 1)
                  vx.push_back(c - 1);
              vx.push_back(b), vx.push_back(c);
              vx.push_back(b + 1), vx.push_back(c + 1);
              event.push_back({a, b, c});
          }
          vx.push_back(1);
          sort(vx.begin(), vx.end());
          vx.erase(unique(vx.begin(), vx.end()), vx.end());
          int m = vx.size();
          build(1, 1, m);
          for(int i = 0; i < n; i++)
          {
              int opt = event[i][0];
              int l = lower_bound(vx.begin(), vx.end(), event[i][1]) - vx.begin() + 1;
              int r = lower_bound(vx.begin(), vx.end(), event[i][2]) - vx.begin() + 1;
              if(opt == 1)
                  modify(1, 1, m, l, r, tag{1, 0});
              else if(opt == 2)
                  modify(1, 1, m, l, r, tag{2, 0});
              else if(opt == 3)
                  modify(1, 1, m, l, r, tag{0, 1});
              cout<<vx[query(1, 1, m) - 1]<<'\n';
          }
          return;
      }
       
      int main()
      {
          std::ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
          
          int TC = 1;
          
          //cin >> TC;    
          for(int tc = 1; tc <= TC; tc++)
          {
              //cout << "Case #" << tc << ": ";         
              solve();
          }
       
       
          return 0;
      }
      

标签:Educational,23,int,Codeforces,mid,seg,tag,stk,id
From: https://www.cnblogs.com/magicat/p/17674011.html

相关文章

  • 2023年8月文章一览
    注:文章时间线被平台弄乱了,本是8月发的,变成了9月了。请忽略。2023年8月编程人总共更新了17篇文章。1.2023年7月文章一览2.ProgrammingAbstractionsinC阅读笔记:p72-p753.BramMoolenar4.ProgrammingabstractionsinC阅读笔记:p76-p835.ProgrammingabstractionsinC阅读笔记:p......
  • py之路——day14-20230902:python内置方法
    作者:zb1、python内置方法:abs()方法:取绝对值all()方法:all(iterable),如果iterable中的所有元素都为空或True,则返回True,否则返回False#all()方法print(all([0,1,-2]))print(all([1,1,2]))print(all([]))D:\oldboy_py\venv\Scripts\python.exeD:/oldboy_py/day4-2023......
  • Educational Codeforces Round 154 (Rated for Div. 2)(A—C)
    A.PrimeDeletion思路:从1到9,每个数后面都可以加一个数构成一个含有两个数的质数,只需要从s[1]~s[9]中找到一个数与s[0]构成质数即可代码实现/*******************************|Author:CHC|Problem:A.PrimeDeletion|Contest:Codeforces-EducationalCodeforcesR......
  • 【230902-1】如图,▲ABC为等腰直角三角形,A为直角,腰长2倍根号2;D为斜边BC中点,E为直角边AC
    【230902-1】如图,▲ABC为等腰直角三角形,A为直角,腰长2倍根号2;D为斜边BC中点,E为直角边AC中点;F为AD上动点,GE垂直EF,GE=EF;H为BC边上动点,连接HE,B‘是B关于HE的轴对称点。求:B’G的最小值?......
  • 【题解】Educational Codeforces Round 153(CF1860)
    每次打都想感叹一句,Educational名不虚传。A.NotaSubstring题目描述:有\(t\)组数据,对于每一组数据,你需要判断能否构造一个只由左右括号组成且长度为已经给定字符串的\(2\)倍且已经给定的字符串不是子串的合法字符串。注:合法的字符串是左右括号能完全匹配的字符串。如果能,......
  • Educational Codeforces Round 113
    稳定发挥4题A题文件输出没去掉WA了一发B题特殊情况没判到,WA了好几发,中间还交到D题去了C题简单判断一下无解,然后组合数求一下就行D题其实也挺简单的,考虑严格夹在两条竖线之间的点(不包括边界),如果它们不是在同一水平线上,则必然大于Manhattan距离,而且两个点对之间要么是x方向走多......
  • Python初级学习20230902——字符串
    字符串"""example05-字符串1.转义问题2.字符编码Author:danlisDate:2023/9/2"""a='hello,world'#和a一样的b="hello,world"#一般长字符串,用三个单引号。三个双引号一般作为注释c='''hello,world'''#......
  • nodejs + superagent 示例记录【2023-09-02】【尝试nodejs接口测试库】
    constsuperagent=require("superagent");(async()=>{ try{  constres=awaitsuperagent.get(   "https://jsonplaceholder.typicode.com/users"  );  constheaderDate=   res.headers&&res.headers.date?......
  • 旧笔记本秒变web服务器---nat123 一款优秀的内网穿透服务器
    2014买的第一台笔记本,win7系统,加过内存,重装过多次系统但是无法运行win10,用来开发已经相当吃力,但运行还是比较流畅的,扔掉可惜,卖二手也卖不了多少,后来经过多次的思考与尝试,将厚重的光驱位扩展了500G硬盘,安装了winNAS,将其改装成了私有NAS网盘,但是客户端只有手机端app,对于我这做web开......
  • macOS Sonoma 14 beta 7 (23A5337a) Boot ISO 原版可引导镜像下载
    macOSSonoma14beta7(23A5337a)BootISO原版可引导镜像下载本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,或者在虚拟机中启动安装。另外也支持在Windows和Linux中创建可引导介质。请访问原文链接:https://sysin.org/blo......