zoukankan      html  css  js  c++  java
  • codeforces 979D Kuro and GCD and XOR and SUM

    题意:

    给出两种操作:

    1.添加一个数字x到数组。

    2.给出s,x,k,从数组中找出一个数v满足gcd(x,k) % v == 0 && x + v <= s && (x xor v 最大),如果没有,输出-1.

    思路:

    有两种做法。

    第一种,首先用若干个set存因子中有k的数字。

    然后每次在set[k]中二分找到大于s-x的第一个数,然后从大到小开始找,假设sum为当前x xor v的最大值,那么当当前的*it +x < sum,那么就直接break,原理是因为a ^ b <= a + b。

    这个没有优化之前是会tle,但是加了优化之后比字典树跑得快了许多。。。

    第二种,对于每一个数,都把它添加到它的因子的01字典树当中去,然后根据x xor v最大这个经典问题,找 xor 最大,字典树是个好东西。

    代码1;

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <set>
     5 #include <math.h>
     6 using namespace std;
     7 const int N = 1e5 + 11;
     8 set<int> mmp[N];
     9 int main()
    10 {
    11     int n;
    12     scanf("%d",&n);
    13     while (n--)
    14     {
    15         int t;
    16         scanf("%d",&t);
    17         if (t == 1)
    18         {
    19             int u;
    20             scanf("%d",&u);
    21             int m = sqrt(1.0 * u);
    22             for (int i = 1;i <= m;i++)
    23             {
    24                 if (u % i == 0)
    25                 {
    26                     mmp[i].insert(u);
    27                     mmp[u/i].insert(u);
    28                 } 
    29             }
    30         }
    31         else
    32         {
    33             int x,k,s;
    34             scanf("%d%d%d",&x,&k,&s);
    35             int sum = -1;
    36             int ans = -1;
    37             if (x % k)
    38             {
    39                 printf("%d
    ",ans);
    40                 continue;
    41             }
    42             auto it = mmp[k].upper_bound(s-x);
    43             if (mmp[k].empty() || it == mmp[k].begin())
    44             {
    45                 printf("%d
    ",ans);
    46                 continue;
    47             }
    48             --it;
    49             for (;it != mmp[k].begin();--it)
    50             {
    51                 if (sum > x + *it) break;
    52                 if (sum < (x ^ *it))
    53                 {
    54                     ans = *it;
    55                     sum = x ^ *it;
    56                 }
    57             }
    58             if (sum < (x ^ *it))
    59             {
    60                 ans = *it;
    61                 sum = x ^ *it;
    62             }
    63             printf("%d
    ",ans);
    64         }
    65     }
    66     return 0;
    67 }

    代码2:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <stdlib.h>
     5 #include <set>
     6 using namespace std;
     7 const int N = 1e5 + 10;
     8 set<int> g[N];
     9 struct node
    10 {
    11     int mi;
    12     struct node* bit[2];
    13     node()
    14     {
    15         mi = N;
    16         bit[0] = bit[1] = nullptr;
    17     }
    18 };
    19 node *a[N];
    20 void update(int x,int u)
    21 {
    22     node* cu = a[x];
    23     cu -> mi = min(cu -> mi,u);
    24     for (int i = 18;i >= 0;i--)
    25     {
    26         int b = u >> i & 1;
    27         if (cu -> bit[b] != nullptr)
    28         {
    29             cu = cu -> bit[b];
    30             cu -> mi = min(cu -> mi,u);
    31         }
    32         else
    33         {
    34             cu -> bit[b] = new node();
    35             cu = cu -> bit[b];
    36             cu -> mi = min(cu -> mi,u);
    37         }
    38     }
    39 }
    40 int que(int x,int k,int s)
    41 {
    42     node *cu = a[k];
    43     if (x % k || cu -> mi > s - x) return -1;
    44     int ret = cu -> mi;
    45     for (int i = 18;i >= 0;i--)
    46     {
    47         int b = x >> i & 1;
    48         if (cu -> bit[b^1] != nullptr && cu -> bit[b^1] -> mi + x <= s)
    49         {
    50             cu = cu -> bit[b^1];
    51             ret = cu -> mi;
    52         }
    53         else
    54         {
    55             cu = cu -> bit[b];
    56             ret = cu -> mi;
    57         }
    58     }
    59     return ret;
    60 }
    61 int main()
    62 {
    63     int q;
    64     for (int i = 1;i < N;i++)
    65     {
    66         for (int j = i;j < N;j += i)
    67         {
    68             g[j].insert(i);
    69         }
    70     }
    71     for (int i = 1;i < N;i++) a[i] = new node();
    72     scanf("%d",&q);
    73     while (q--)
    74     {
    75         int t;
    76         scanf("%d",&t);
    77         if (t==1)
    78         {
    79             int u;
    80             scanf("%d",&u);
    81             for (auto x : g[u])
    82             {
    83                 update(x,u);
    84             }
    85         }
    86         else
    87         {
    88             int x,s,k;
    89             scanf("%d%d%d",&x,&k,&s);
    90             int ans = que(x,k,s);
    91             printf("%d
    ",ans);
    92         }
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    写一个简单的 Linux Shell (C++)
    操作系统课程设计的技巧与踩坑
    Power Designer建模之餐饮在线点评系统——概念数据模型
    Power Designer建模之餐饮在线点评系统——业务处理模型
    Power Designer建模之餐饮在线点评系统——需求模型实例
    使用本地json-server服务,创建简单的本地api数据
    从入门到入土JS知识(一):关系操作符和相等操作符
    工作中用到的小脚本2
    绕WAF(Bypass)--随时更新
    关于FastJson漏洞的一切(未完待续)
  • 原文地址:https://www.cnblogs.com/kickit/p/9046953.html
Copyright © 2011-2022 走看看