zoukankan      html  css  js  c++  java
  • CF1101

    D:题意:树上每个顶点有个权值,求最长链,满足链上gcd > 1

    解:对每个质数建虚树,每个点只会拆成log个点,所以是log2的。

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 200010;
      4 
      5 struct Edge {
      6     int nex, v, len;
      7 }edge[N << 1], EDGE[N << 1]; int tp, TP;
      8 
      9 int p[N], top, e[N], pos2[N], num2, ST[N << 1][20], pw[N << 2], n, ans, id[N], last[N];
     10 int vis[N];
     11 int imp[N], K, E[N], val[N], fa[N], d[N], stk[N], use[N], Time, RT, f[N];
     12 std::vector<int> v[N];
     13 
     14 inline void add(int x, int y) {
     15     tp++;
     16     edge[tp].v = y;
     17     edge[tp].nex = e[x];
     18     e[x] = tp;
     19     return;
     20 }
     21 
     22 inline void ADD(int x, int y) {
     23     TP++;
     24     EDGE[TP].v = y;
     25     EDGE[TP].len = d[y] - d[x];
     26     EDGE[TP].nex = E[x];
     27     E[x] = TP;
     28     return;
     29 }
     30 
     31 inline void getp(int n) {
     32     for(int i = 2; i <= n; i++) {
     33         if(!vis[i]) {
     34             p[++top] = i;
     35             last[i] = i;
     36             id[i] = top;
     37         }
     38         for(int j = 1; j <= top && i * p[j] <= n; j++) {
     39             vis[i * p[j]] = 1;
     40             last[i * p[j]] = p[j];
     41             if(i % p[j] == 0) break;
     42         }
     43     }
     44     return;
     45 }
     46 
     47 void DFS_1(int x, int f) {
     48     fa[x] = f;
     49     d[x] = d[f] + 1;
     50     pos2[x] = ++num2;
     51     ST[num2][0] = x;
     52     for(int i = e[x]; i; i = edge[i].nex) {
     53         int y = edge[i].v;
     54         if(y == f) {
     55             continue;
     56         }
     57         DFS_1(y, x);
     58         ST[++num2][0] = x;
     59     }
     60     return;
     61 }
     62 
     63 inline void prework() {
     64     for(int i = 2; i <= num2; i++) pw[i] = pw[i >> 1] + 1;
     65     for(int j = 1; j <= pw[num2]; j++) {
     66         for(int i = 1; i + (1 << j) - 1 <= num2; i++) {
     67             if(d[ST[i][j - 1]] < d[ST[i + (1 << (j - 1))][j - 1]])
     68                 ST[i][j] = ST[i][j - 1];
     69             else
     70                 ST[i][j] = ST[i + (1 << (j - 1))][j - 1];
     71         }
     72     }
     73     return;
     74 }
     75 
     76 inline int lca(int x, int y) {
     77     x = pos2[x];
     78     y = pos2[y];
     79     if(x > y) std::swap(x, y);
     80     int t = pw[y - x + 1];
     81     if(d[ST[x][t]] < d[ST[y - (1 << t) + 1][t]])
     82         return ST[x][t];
     83     else
     84         return ST[y - (1 << t) + 1][t];
     85 }
     86 
     87 inline bool cmp(const int &a, const int &b) {
     88     return pos2[a] < pos2[b];
     89 }
     90 
     91 inline void work(int x) {
     92     if(use[x] != Time) {
     93         use[x] = Time;
     94         f[x] = 0;
     95         E[x] = 0;
     96     }
     97     return;
     98 }
     99 
    100 inline void build_t() {
    101     std::sort(imp + 1, imp + K + 1, cmp);
    102     TP = top = 0;
    103     work(imp[1]);
    104     stk[++top] = imp[1];
    105     for(int i = 2; i <= K; i++) {
    106         int x = imp[i], y = lca(x, stk[top]);
    107         work(x); work(y);
    108         while(top > 1 && pos2[y] <= pos2[stk[top - 1]]) {
    109             ADD(stk[top - 1], stk[top]);
    110             top--;
    111         }
    112         if(y != stk[top]) {
    113             ADD(y, stk[top]);
    114             stk[top] = y;
    115         }
    116         stk[++top] = x;
    117     }
    118     while(top > 1) {
    119         ADD(stk[top - 1], stk[top]);
    120         top--;
    121     }
    122     RT = stk[top];
    123     return;
    124 }
    125 
    126 void DFS(int x) {
    127     int a = 0, b = 0;
    128     for(int i = E[x]; i; i = EDGE[i].nex) {
    129         int y = EDGE[i].v;
    130         DFS(y);
    131         if(EDGE[i].len > 1) continue;
    132         if(f[y] > a) {
    133             b = a;
    134             a = f[y];
    135         }
    136         else b = std::max(b, f[y]);
    137     }
    138     if(vis[x] == Time) {
    139         ans = std::max(ans, a + b + 1);
    140         f[x] = a + 1;
    141     }
    142     return;
    143 }
    144 
    145 int main() {
    146     getp(N - 1);
    147     memset(vis, 0, sizeof(vis));
    148     int tot = top, flag = 1;
    149 
    150     scanf("%d", &n);
    151     for(int i = 1; i <= n; i++) {
    152         scanf("%d", &val[i]);
    153         int x = val[i];
    154         if(x > 1) flag = 0;
    155         while(x > 1) {
    156             int y = last[x];
    157             while(x % y == 0) {
    158                 x /= y;
    159             }
    160             v[id[y]].push_back(i);
    161         }
    162     }
    163     for(int i = 1, x, y; i < n; i++) {
    164         scanf("%d%d", &x, &y);
    165         add(x, y); add(y, x);
    166     }
    167 
    168     if(flag) {
    169         puts("0");
    170         return 0;
    171     }
    172 
    173     DFS_1(1, 0);
    174     prework();
    175 
    176     for(int i = 1; i <= tot; i++) {
    177         K = 0;
    178         ++Time;
    179         for(int j = 0; j < (int)v[i].size(); j++) {
    180             imp[++K] = v[i][j];
    181             vis[v[i][j]] = Time;
    182         }
    183         build_t();
    184         DFS(RT);
    185     }
    186 
    187     printf("%d 
    ", ans);
    188     return 0;
    189 }
    AC代码

    G:题意:给定序列,你要把它分成尽可能多的几段,每段的权值是异或和。

    要求没有哪些段的权值异或和为0。输出最大段数。无解-1。

    解:考虑无解,肯定是总异或和为0。否则一定存在解。

    发现这个东西,其实等价于选出一些前缀,因为异或可以抵消,所以这些前缀能表示出的和这些段能表示出的是相同的。

    然后就把前缀插入线性基,看能插入多少个。

    看到异或就要想线性基。

     1 #include <bits/stdc++.h>
     2 
     3 const int N = 200010;
     4 
     5 int b[32], a[N];
     6 
     7 inline int insert(int x) {
     8     for(int i = 30; i >= 0 && x; i--) {
     9         if(((x >> i) & 1) == 0) continue;
    10         if(b[i]) x ^= b[i];
    11         else {
    12             b[i] = x;
    13             return 1;
    14         }
    15     }
    16     return 0;
    17 }
    18 
    19 int main() {
    20 
    21     int n;
    22     scanf("%d", &n);
    23     for(int i = 1; i <= n; i++) {
    24         scanf("%d", &a[i]);
    25         a[i] ^= a[i - 1];
    26     }
    27 
    28     if(!a[n]) {
    29         printf("-1
    ");
    30         return 0;
    31     }
    32 
    33     int cnt = 0;
    34     for(int i = n; i >= 1; i--) {
    35         cnt += insert(a[i]);
    36     }
    37 
    38     printf("%d 
    ", cnt);
    39     return 0;
    40 }
    AC代码
  • 相关阅读:
    CS1704问题汇总
    Android hdpi ldpi mdpi xhdpi xxhdpi适配详解
    Mac开发工具汇总
    Objective-C语法之代码块(block)的使用 (转载)
    iOS学习之Object-C语言属性和点语法(转载收集)
    object-c中疑问
    Android ListVeiw控件(转载整理)
    Android Studio--》Gradle Scripts配置说明
    xutils android studio引用问题
    15 个 Android 通用流行框架大全(转载)
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10600383.html
Copyright © 2011-2022 走看看