ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CJ 8.31 test

2019-09-03 22:52:09  阅读:229  来源: 互联网

标签:CJ freopen int 复杂度 异或 8.31 ans test dis


A

j打成i然后100->0.
我们先考虑把第一个操作并到第二个操作里面。
显然把某二进制位取反等于异或上\(2^i\)。
去个重应该可以降一点复杂度。最多38个元素。
我们现在把要做的变成了求使用一个数组中的元素\(\{a_1,\cdots,a_n\}\)相互异或成\(p=s\oplus t\)的最短步数。
我们可以用bfs来做一个类似最短路的问题,对于每一个询问,我们可以在计算出当前答案之后停止计算,等之后的询问需要计算时继续计算。
并且\(dis\)数组一开始可以设置为只异或上\(2^i\)变成\(0\)的最短步数,可以降一点复杂度。
实际上并不需要这些剪枝。


#include<bits/stdc++.h>
using namespace std;
const int P=998244353,N=262144;
int dis[N],d[N],a[39];
queue<int>q;
int read(){int x=0;char c=getchar();while(c<48||c>57)c=getchar();while(c>=48&&c<=57)x=x*10+c-48,c=getchar();return x;}
int inc(int a,int b){a+=b;return a>=P? a-P:a;}
int mul(int a,int b){return 1ll*a*b%P;}
int main()
{
    freopen("A.in","r",stdin),freopen("A.out","w",stdout);
    int T,n,m,Q,i,j,p,x,ans=0;
    for(i=1;i<N;++i) d[i]=d[i^(i&-i)]+1;
    for(T=read();T;--T)
    {
    m=read(),Q=read(),n=ans=0,memcpy(dis,d,sizeof dis);
    while(!q.empty()) q.pop();
    for(x=1;x<N;x<<=1) dis[x]=1,q.push(x),a[++n]=x;
    for(i=1;i<=m;++i){x=read();if(dis[x]^1)dis[x]=1,q.push(x),a[++n]=x;}
    for(i=1;i<=Q;++i)
    {
        p=read()^read();
        while(!q.empty())
        {
        x=q.front(); if(dis[x]>=dis[p]) break; q.pop();
        for(j=1;j<=n;++j) if(dis[x^a[j]]>dis[x]+1) dis[x^a[j]]=dis[x]+1,q.push(x^a[j]);
        }
        ans=inc(ans,mul(i,dis[p]));
    }
    printf("%d\n",ans);
    }
}

C

标签:CJ,freopen,int,复杂度,异或,8.31,ans,test,dis
来源: https://www.cnblogs.com/cjoierShiina-Mashiro/p/11456250.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有