Codeforces Round #430 (Div. 2) 题解

来源:互联网 发布:西安市高新区软件新城 编辑:程序博客网 时间:2024/05/18 13:47

Codeforces Round #430 (Div. 2)
A:

#include<bits/stdc++.h>using namespace std;typedef long long ll;int main(){    int l,r,x,y,k;    cin >> l >> r >> x >> y >> k;    bool ok=false;    for(int i=l;i<=r;++i)    {        if(i%k==0&&i/k>=x&&i/k<=y) ok=true;    }    cout << (ok?"YES":"NO") << endl;    return 0;}

B:

#include<bits/stdc++.h>using namespace std;typedef long long ll;const double eps=1e-10;double dis(double x,double y){    return sqrt(x*x+y*y);}int main(){    double d,r;    int n;    scanf("%lf%lf",&r,&d);    scanf("%d",&n);    double L=(r-d),R=r;    int ans=0;    for(int i=0;i<n;++i)    {        double x,y,rd;        scanf("%lf%lf%lf",&x,&y,&rd);        double k=dis(x,y);        if(k-L>=rd&&R-k>=rd) ++ans;    }    printf("%d\n",ans);    return 0;}

C:
考虑用 set 维护所有的祖先变 0 的不同的 gcd 和不变 0gcd 。这种 gcd 的个数最多为 logn 个。当且仅当不变 0gcd 在某一结点处发生变化时放入 set
空间复杂度是 O(nlogn) ,时间复杂度是 O(nlognlog(logn))

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e5+7;int a[N],ans[N],now[N];inline int Max(int a,int b ){ return a>b?a:b; }int gcd(int a,int b) { return a%b?gcd(b,a%b):b; }vector<int> adj[N];set<int> s[N];void dfs(int u,int p){    for(int k : s[u]) ans[u]=Max(ans[u],k);    ans[u]=Max(ans[u],now[u]);    for(int v : adj[u])    {        if(v==p) continue;        now[v]=gcd(now[u],a[v]);        for(int k : s[u]) s[v].insert(gcd(k,a[v]));        if(now[v]!=now[u]) s[v].insert(now[u]);        dfs(v,u);    }}int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;++i) scanf("%d",&a[i]);    for(int i=1;i<n;++i)    {        int u,v;        scanf("%d%d",&u,&v);        adj[u].push_back(v);        adj[v].push_back(u);    }    ans[1]=now[1]=a[1];    s[1].insert(0);    for(int v : adj[1])    {        now[v]=gcd(now[1],a[v]);        for(int k : s[1]) s[v].insert(gcd(k,a[v]));        if(now[v]!=now[1]) s[v].insert(now[1]);        dfs(v,1);    }    for(int i=1;i<=n;++i) printf("%d%c",ans[i],i==n?'\n':' ');    return 0;}

D:
题意可以很轻松的转化为:每个询问给定一个整数 q, 求满足 qk 在数组中存在的最小的 k
可以先将数组中的所有元素放入01Trie 中,每次询问,对于 q 的某一位 b 来说,Trieb 方向是左子树,如果左子树不满,访问左子树,否则访问右子树。最后得到的就是最小的 k

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=3e5+7;int a[N];struct Trie{    int next[N*20][2],sz[N*20],L,root,M=18;    int newnode()    {        next[L][1]=next[L][0]=-1;        sz[L]=0;        return L++;    }    void init()    {        L=0;        root=newnode();    }    int query(int x)    {        int now=root,res=0;        for(int i=M;i>=0;--i)        {            int b=((x>>i)&1);            if(next[now][b]==-1) return res;            if(sz[next[now][b]]<(1<<i)) now=next[now][b];            else            {                res|=(1<<i);                if(next[now][b^1]==-1) return res;                now=next[now][b^1];            }        }        return res;    }    void insert(int x)    {        int now=root;        ++sz[now];        for(int i=M;i>=0;--i)        {            int b=(x>>i)&1;            if(next[now][b]==-1) next[now][b]=newnode();            now=next[now][b];            ++sz[now];        }        if(sz[now]>1)        {            now=root;            --sz[now];            for(int i=M;i>=0;--i)            {                int b=(x>>i)&1;                now=next[now][b];                --sz[now];            }        }    }};Trie t;int main(){    int n,m;    scanf("%d%d",&n,&m);    t.init();    for(int i=1;i<=n;++i)    {        int k;        scanf("%d",&k);        t.insert(k);    }    int now=0;    for(int i=1;i<=m;++i)    {        int k;        scanf("%d",&k);        now^=k;        printf("%d\n",t.query(now));    }    return 0;}
原创粉丝点击