• 一些杂题(9.23)


    八月赛

    A. Extra Large Knapsack

    我的思路

    是否可行只要看所有异或在一起是否为0就可以了

    可行的方案只要有一个在第一个包里,剩下的都在第二个包里就可以了

    注意:n==1的时候不可行,要特判

    代码

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. ios::sync_with_stdio(0);cin.tie(0);
    6. int T;cin>>T;
    7. while(T--){
    8. int n;cin>>n;int sum=0,w=0;
    9. for(int i=0;i
    10. cin>>w;
    11. sum=sum^w;
    12. }
    13. if(n!=1&&!sum){
    14. cout<<"Yes\n";
    15. cout << 0;
    16. for(int i = 1; i < n; i++) cout << 1;
    17. cout<<'\n';
    18. }
    19. else{
    20. cout<<"No\n";
    21. }
    22. }
    23. return 0;
    24. }

    P4551 最长异或路径

    P4551 最长异或路径t

    题意:

    前置知识 字符串Trie

    之前学过string中的Trie,一个节点一共有26个指针,u是当前节点的编号,a[u][c-'a']用来存储下一个结点的序号

    思路 XOR Trie+贪心

    一道相比较而言更简单的题目:#10050.  The XOR Largest Pair 

    上面这道题目中,把每个在a数组里的数字都遍历了,找a[i]能够找到的异或最大值,更新最后的最大值就可以了;因为一个数字最长32位,顺着Trie下去找32次就可以了;所以总时间复杂度是O(32n)

    代码

    注意1<<31要 long long

    1. #include
    2. using namespace std;
    3. #define int long long
    4. int a[10000005][2];int ans=0;int v[100005];int cnt=0;
    5. void insert(int x){
    6. int p=0;
    7. for(int i=(long long)1<<31;i;i>>=1){
    8. if(i&x){
    9. if(!a[p][1]){a[p][1]=++cnt;}
    10. p=a[p][1];
    11. }
    12. else{
    13. if(!a[p][0]){a[p][0]=++cnt;}
    14. p=a[p][0];
    15. }
    16. }//上面在造树
    17. return;
    18. }
    19. int search(int x){
    20. int p=0;int sum=0;
    21. for(int i=(long long)1<<31;i;i>>=1){
    22. int flag=i&x;
    23. if(i&x){//如果当前是1,那就要找0
    24. if(a[p][0]){//如果0存在的话
    25. p=a[p][0];sum=sum|i;
    26. }
    27. else p=a[p][1];
    28. }
    29. else{
    30. if(a[p][1]){//如果1存在的话
    31. p=a[p][1];sum=sum|i;
    32. }
    33. else p=a[p][0];
    34. }
    35. }
    36. return sum;
    37. }
    38. signed main()
    39. {
    40. int n;cin>>n;
    41. for(int q=0;q
    42. cin>>v[q]; insert(v[q]);
    43. }
    44. for(int q=0;q
    45. ans=max(ans,search(v[q]));
    46. }
    47. cout<
    48. return 0;
    49. }

    会了上面这道题,再来看看P4551

    思路

    可以分为两个子问题,(1)所有结点到根结点的距离D(x) (2)D(x)数组中两个最大的异或和

    第一个子问题可以用dfs来解决;第二个子问题可以用上面的01树解决

    1. #include
    2. using namespace std;
    3. #define int long long
    4. vectorint,int> >mp[100004];int n;
    5. int D[100005];
    6. int a[10000006][2];int cnt=0;int sum=0;
    7. void dfs(int x,int fa,int w){
    8. for(auto q:mp[x]){
    9. D[x]=D[fa]^w;//
    10. if(q.first==fa)continue;
    11. dfs(q.first,x,q.second);
    12. }
    13. }
    14. void tinsert(int x){
    15. int p=0;
    16. for(int i=(long long)1<<31;i;i>>=1){
    17. if(i&x){
    18. if(!a[p][1]){a[p][1]=++cnt;}
    19. p=a[p][1];
    20. }
    21. else{
    22. if(!a[p][0]){a[p][0]=++cnt;}
    23. p=a[p][0];
    24. }
    25. }//上面在造树
    26. return;
    27. }
    28. int search(int x){
    29. int p=0;int ans=0;
    30. for(int i=(long long)1<<31;i;i>>=1){
    31. bool flag=i&x;
    32. if(a[p][!flag]){ans=ans|i;p=a[p][!flag];}
    33. else
    34. p=a[p][flag];
    35. }
    36. return ans;
    37. }
    38. signed main()
    39. {
    40. cin>>n;
    41. for(int i=0;i-1;i++){
    42. int u,v,w;cin>>u>>v>>w;
    43. mp[u].push_back({v,w}); mp[v].push_back({u,w});
    44. }//树建好了
    45. dfs(1,0,0);//D[x]准备好了
    46. for(int i=1;i<=n;i++) tinsert(D[i]);//建字典树
    47. for(int i=1;imax(sum,search(D[i]));
    48. cout<
    49. return 0;
    50. }

    CF126B Password

    给你一个字符串S(|S|<=1000000),找到既是S前缀又是S后缀又在S中间出现过(既不是S前缀又不是S后缀)的最长子串,如果不存在输出“Just a legend”。

    方法一 哈希

    要注意的是找最长的字符串 符合二分的特性

    1. #include
    2. using namespace std;
    3. const int N = 1000000 + 5;
    4. const unsigned long long base = 163;
    5. string s;
    6. unsigned long long has[N];
    7. unsigned long long p[N];int n;
    8. //unsigned long long 自动 mod 2^64
    9. //s[]是读入的数组
    10. //p[]预处理存储p的n次方,计算区间时候会用到
    11. //hash[]存储对应字符串的哈希值
    12. void init(){ //处理hash值
    13. p[0]=1; //p的0次方为1
    14. has[0]=0;
    15. n = s.size()-1;
    16. for(int i=1;i<=n;i++) p[i]=p[i-1]*base;
    17. for(int i=1;i<=n;i++) has[i]=has[i-1]*base+(s[i]-'a');
    18. }
    19. unsigned long long get(int l, int r){//取出g里[l,r]里面的字符串的hash值
    20. return has[r]-has[l-1]*p[r-l+1];
    21. }
    22. int main()
    23. {
    24. cin>>s;s='#'+s;
    25. init();vector<int> dp;//从1开始到flag都是
    26. for(int i=1;i//可以不等于n,因为如果是n就是字符串自己了 // 不可以break
    27. if(get(1,i)==get(n-i+1,n)) {
    28. dp.push_back(i);
    29. }
    30. }
    31. int l=0,r=dp.size()-1,ans=0,mid;
    32. while(l<=r){
    33. mid=(l+r)/2;bool flag=0;
    34. for(int i=2;i+dp[mid]-1//dp[mid]是长度,不等于n是因为不能和后缀的相同
    35. if(get(1,dp[mid])==get(i,i+dp[mid]-1)){
    36. ans=dp[mid];l=mid+1;
    37. flag=1;break;//存在就可以break了
    38. }
    39. }
    40. if(!flag)r=mid-1;
    41. }
    42. if(!ans)cout<<"Just a legend\n";
    43. else cout<substr(1,ans);
    44. return 0;
    45. }

  • 相关阅读:
    创建最基本的web服务器-http模块
    SpringBoot+SpringMVC+MybatisPlus
    浅谈JS中null的江湖地位
    单例模式 饿汉式和懒汉式的区别
    搞了三天终于成功跑起来GitHub上的vue-element-admin最新解决办法!(mac系统亲测有效)
    想做FP独立站?众多平台他为何脱颖而出
    leetcode分类刷题:栈(Stack)(三、下一个更大的数)
    数据库管理-第115期 too many open files(202301107)
    华为机试HJ9
    toon boom harmony基础
  • 原文地址:https://blog.csdn.net/zy98zy998/article/details/132712428