首页 > 其他分享 >AtCoder Regular Contest 127

AtCoder Regular Contest 127

时间:2023-04-10 19:11:09浏览次数:44  
标签:AtCoder ch int 元素 -- 异或 Regular 127 oplus

D - LIS 2

难搞的地方在于取min,考虑比较\((a_i \oplus a_j,b_i \oplus b_j)\)两者的过程:是在它们第一位不一样的地方比较,取该位为0的那个。
而判断两个数在某位是否相等,可以想到异或操作,然后把这两者异或起来后,由异或运算的交换律可得等价于\((a_i \oplus b_i) \oplus (a_j \oplus b_j)\),这样就转成两个位置独立的式子的异或值,然后枚举这个第一个为1的位置,在trie树上记一些东西,再类似地查一下就行。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+5,M=18;
int n,a[N],b[N],ch[N][2],cnt=1;
ll tot[N][2],suma[N][2][M],sumb[N][2][M];
int main() {
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    for(int i=1;i<=n;i++){
        int z=(a[i]^b[i]);
        int u=1;
        for(int p=M-1;p>=0;p--){
            int q=(z&(1<<p))>>p,v=(a[i]&(1<<p))>>p;
            if(!ch[u][q]) ch[u][q]=++cnt;
            u=ch[u][q];
            for(int k=0;k<M;k++){
                if(a[i]&(1<<k)) suma[u][v][k]++;
                if(b[i]&(1<<k)) sumb[u][v][k]++;
            }
            tot[u][v]++;
        }
    }
    ll ans=0;
    for(int i=1;i<=n;i++){
        //cout<<"i="<<i<<endl;
        int z=(a[i]^b[i]);
        int u=1;
        for(int p=M-1;p>=0;p--){
            int q=(z&(1<<p))>>p;
            int cur=ch[u][!q];

            int v=(a[i]&(1<<p))>>p;
            //v=(!v);
            for(int k=0;k<M;k++){
                if(a[i]&(1<<k)) ans+=(tot[cur][v]-suma[cur][v][k])*(1<<k);
                else ans+=suma[cur][v][k]*(1<<k);
            }
            //cout<<ans<<endl;
            v=(!v);
            for(int k=0;k<M;k++){
                if(b[i]&(1<<k)) ans+=(tot[cur][v]-sumb[cur][v][k])*(1<<k);
                else ans+=sumb[cur][v][k]*(1<<k);
            }
            u=ch[u][q];
            //cout<<p<<" "<<ans<<endl;
        }
        int cur=u;
        for(int v=0;v<2;v++)
            for(int k=0;k<M;k++){
                if(a[i]&(1<<k)) ans+=(tot[cur][v]-suma[cur][v][k])*(1<<k);
                else ans+=suma[cur][v][k]*(1<<k);
            }
        //cout<<"ans="<<ans<<endl;
    }
    cout<<ans/2<<endl;
    return 0;
}

E - Priority Queue

一般的思路是,考虑如何判断某个最终集合是否合法,但这样会得到非常复杂的转移,不是很可做。
从边界的角度,考虑令留下的集合最小和最大的情况(非严格定义,感性理解):最小显然可以做到删掉最大的那些元素;最大就是从小到大加入元素。然后发现这样做之后,对一个数\(v\),最小的做法使得小于它的元素最多;而最大的做法使得大于它的元素最多。
然后考虑把最终留下的元素升序排序,则对于某个合法的答案,每个元素必须要在,上面得出的对应位置的值作为上下界的区间内。(由上面的结论可以反证出来)
然后可以证明,这个条件是充分的。因为对于留下的最大的集合(删去的最小),一定可以通过修改,将本来要删掉的集合换成更大的(直接一一对应过去即可)。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N=10005,P=998244353;
void inc(int& x,int y){
    x+=y;
    if(x>=P) x-=P;
    if(x<0) x+=P;
}
int sum(int x,int y){
    x+=y;
    if(x>=P) x-=P;
    if(x<0) x+=P;
    return x;
}
void mul(int& x,int y){
    x=1ll*x*y%P;
}
int prd(int x,int y){
    return 1ll*x*y%P;
}
int n,m,a[N],mx[N];
set<int>st;
int pos[N],f[N][N];
int main() {
    cin>>n>>m;
    for(int i=1;i<=n;i++) mx[i]=1;
    int tot=0;
    for(int i=1;i<=n+m;i++){
        int x;
        scanf("%d",&x);
        if(x==1){
            st.insert(++tot);
        }
        else{
            set<int>:: iterator it=st.end();
            it--;
            mx[*it]=0;
            st.erase(it);
        }
    }
    for(int i=1,j=0;i<=n;i++) if(mx[i]) pos[++j]=i;//cout<<pos[j]<<" "; puts("");
    f[0][0]=1;
    for(int j=1;j<=n;j++) inc(f[0][j],f[0][j-1]);
    for(int i=1;i<=n-m;i++){
        for(int j=1;j<=pos[i];j++) f[i][j]=f[i-1][j-1];
        for(int j=1;j<=n;j++) inc(f[i][j],f[i][j-1]);
    }
    cout<<f[n-m][n]<<endl;
    return 0;
}

标签:AtCoder,ch,int,元素,--,异或,Regular,127,oplus
From: https://www.cnblogs.com/szsz/p/17302839.html

相关文章

  • 3500/15 127610-01 对于高性能市场中的云计算
    3500/15127610-01对于高性能市场中的云计算对于高性能市场中的云计算,产品设计将基于性能。在PC系统架构方面,PCIe4.016G和即将推出的PCIe5.032G有一些主要的技术改进。CXL基于PCIe4.0,以增强该结构中的高速组件。面向云计算的网络切片、网络功能虚拟化(NFV)和面向5G边缘服务......
  • AtCoder Regular Contest 159
    Preface这周六紧张刺激的一日三赛,上午蓝桥杯,晚上ARC之后隔5min就是CF,可谓是手搓键盘到冒烟的一天了这场其实打的感觉很没水准,B刚开始没想清楚很多边界条件挂了三发,45min左右才过然后C的构造也不太会,随便写了个暴力也是挂挂挂,只好弃了去写D题了结果发现D题好像是个不难的线段树......
  • 练习记录- AtCoder Beginner Contest 295(D)
    vp的觉得我的D很聪明所以来写一下(乐D-ThreeDaysAgo题意就是求所有字符出现次数均为偶数的字串数量太笨了所以想了很久我把存在奇数个1当作第2位是2那么当经过了两次1 2^2这个2就变成了02就是第二位就是4...以此类推 所以我遍历一遍字符串求出当前的异或......
  • 练习记录-AtCoder Beginner Contest 296(A-F)
    vp的感觉整场挺智慧A-Alternately找有没有连续的男女#include<bits/stdc++.h>#defineclosestd::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)usingnamespacestd;typedeflonglongll;constllMAXN=3e5+7;constllmod=1e9+7;constllinf=0x3......
  • AtCoder Beginner Contest 278
    口胡一下,从青色开始E-GridFilling给定一个W×H的矩阵,每个格子有一个数,在1和N之间,给定w<=W,h<=H,对于每个满足1<=i<=W-w+1,1<=j<=H-h+1的格子(i,j),求以它为左上角的w×h矩阵被遮住后整个大矩阵还剩下几种数字。W,H,N,w,h<=300首先我们看见这个熟悉的300就知道是立方算法又注......
  • [ARC127D] Sum of Min of Xor 题解
    先把\(i\)对\(j\)的约束去掉。没有\(\min\)的情况是trival的,发现瓶颈在于如何比较两个数之间的大小。可以发现,对两个二进制数,我们本质上是想要找到它们第一个不同的位置。于是考虑从最高位开始,将\((a_i,b_i)\)按最高位分组为\((0,0),(0,1),(1,0),(1,1)\)四组。每组内......
  • AtCoder ABC286 C - Chinese Restaurant
    AtCoderABC286C-ChineseRestaurant题目描述有\(N\)个人从\(0\)开始编号,按逆时针顺序间隔均匀地坐在转盘周围。在开始时,第\(p_i\)盘菜在第\(i\)个人的前面。现在,你可以进行以下操作\(0\)次或多次。将转盘逆时针旋转\(\dfrac{1}{N}\)圈。也就是说,旋转前......
  • AtCoder ABC295 D - Three Days Ago
    AtCoderABC295D-ThreeDaysAgo题目描述给出一个数字串,问有多少子段满足,可以以某种方式将这个子段重排,将子段分成两个完全相同的部分。样例输入输出202303224\((1,6)(1,8)(2,7)(7,8)\)都可以满足条件分析如果要满足某一个字段可以被分为两个相同的部分,则不......
  • AtCoder ABC294 F - Sugar Water 2
    AtCoderABC294F-SugarWater2题意有\(2\)排糖和水。第\(1\)排有\(N\)瓶糖和\(N\)瓶水。糖分别有\(A_i\)克,水分别有\(B_i\)克。第\(2\)排有\(M\)瓶糖和\(M\)瓶水,糖分别有\(C_i\)克,水分别有\(D_i\)克。若要从第\(1\)排糖水中找到\(A_i\)克糖和......
  • [oeasy]python0127_中文系统_gbk_BIG5_南极星_内码转化
    中文系统bgk回忆上次内容汉字字形通过点阵式打字机像素级寻址的屏幕进入了计算机的世界在海峡对岸的台湾同胞也进入了汉字时代他们会使用GB2312编码吗?能互通吗?......