zoukankan      html  css  js  c++  java
  • 牛客网暑期ACM多校训练营(第一场)菜鸟补题QAQ

      签到题 J Different Integers(树状数组)

      题目大意:给一个长为n的数组,每一个询问给两个数字i, j ,询问1~i, j~n这两个区间中有多少不同的数字,真的像是莫队裸题,但是两个区间是分隔的,所以可以考虑将数组延长一倍,即num[i] = num[i+n],这样就可以变成一段区间中查询了,不过这样会T.....参考了题解的做法还是比较好用的,写法非常巧妙。记录数字i第一次和最后一次出现的位置分别为first[i], last[i],按每个询问的rhs从小到大排序后,遍历num数组。遍历序号为i,每次遍历处理询问和维护一个树状数组,①只有当某个询问的 rhs == i 时处理该询问②维护树状数组,首先我们可以想到假如某个数x,当last[x] == i 时,下个遍历时下个询问的rhs必然会大于这个last[x](因为是从1~n遍历),所以当这次遍历过后,剩下的询问rhs全部大于last[x],所有右边区间rhs~n已经没有x了,这个时候只要看前面lhs是不是小于first[x]就知道这个数在不在询问区间了,这个时候就可以维护一个前缀和,sum[i]表示表示有多少个数的first值是在1~i内的。

      1 #include <iostream>
      2 #include <string.h>
      3 #include <cstdio>
      4 #include <vector>
      5 #include <map>
      6 #include <string>
      7 #include <algorithm>
      8 #include <time.h>
      9  
     10 #define SIGMA_SIZE 26
     11 #define lson rt<<1
     12 #define rson rt<<1|1
     13 #define  lowbit(x) (x&-x)
     14 #pragma warning ( disable : 4996 )
     15  
     16 using namespace std;
     17 typedef long long LL;
     18 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
     19 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
     20 inline int Max(int a,int b)    { return a>b?a:b; }
     21 inline int Min(int a,int b)    { return a>b?b:a; }
     22 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
     23 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
     24 const LL INF = 0x3f3f3f3f3f3f3f3f;
     25 const LL mod  = 1000000007;
     26 const double eps = 1e-8;
     27 const int inf  = 0x3f3f3f3f;
     28 const int maxk = 1e4+5;
     29 const int maxn = 1e5+10;
     30  
     31 int n, q, tot;
     32 int first[maxn], last[maxn];
     33 int num[maxn], ans[maxn], _count[maxn];
     34  
     35 struct node {
     36     int lhs, rhs, id;
     37 }p[maxn];
     38  
     39 void add( int x, int d )
     40 {
     41     while ( x > 0 )
     42     {
     43         _count[x] += d;
     44         x -= lowbit(x);
     45     }
     46 }
     47  
     48 int sum(int x)
     49 {
     50     int s = 0;
     51     while ( x <= n )
     52     {
     53         s += _count[x];
     54         x += lowbit(x);
     55     }
     56     return s;
     57 }
     58  
     59 bool cmp(const node& a, const node &b)
     60 { return a.rhs < b.rhs; }
     61  
     62 void init()
     63 {
     64     tot = 0;
     65     memset(first, -1, sizeof(first));
     66     memset(last, -1, sizeof(last));
     67     memset(_count, 0, sizeof(_count));
     68      
     69     for (int i = 1; i <= n; i++)
     70     {
     71         scanf("%d", &num[i]);
     72         if (first[num[i]] == -1)
     73             { tot++; first[num[i]] = i;}
     74         last[num[i]] = i;
     75     }
     76  
     77     for (int i = 1; i <= q; i++)
     78     {
     79         scanf("%d %d", &p[i].lhs, &p[i].rhs);
     80         p[i].id = i;
     81     }
     82     sort(p+1, p+1+q, cmp);
     83 }
     84  
     85  
     86 int main()
     87 {
     88     while (~scanf("%d %d", &n, &q))
     89     {
     90         init();
     91  
     92         for (int i = 1, k = 1; i <= n; i++)
     93         {   //如果有边界到达了某一点i,则可以开始处理左边界
     94             while (k <= q && p[k].rhs == i)
     95             {
     96                 ans[p[k].id] = tot - sum(p[k].lhs);
     97                 k++;
     98             }
     99  
    100             if (last[num[i]] == i)
    101                 add(first[num[i]]-1, 1);
    102         }
    103  
    104         for ( int i = 1; i <= q; i++ )
    105             printf("%d
    ", ans[i]);
    106     }
    107  
    108     return 0;
    109 }
    View Code

      

      签到题? D Two Graphs 

      题目大意:给两个简单图G1(V, E1), G2(V,E2) ,问有多少个G2的子图与G1是同构的,想了好多骚操作,,结果hash去重就可以了

     1 #include <iostream>
     2 #include <string.h>
     3 #include <cstdio>
     4 #include <vector>
     5 #include <set>
     6 #include <string>
     7 #include <algorithm>
     8 #include <time.h>
     9  
    10 #define SIGMA_SIZE 26
    11 #define lson rt<<1
    12 #define rson rt<<1|1
    13 #define  lowbit(x) (x&-x)
    14 #pragma warning ( disable : 4996 )
    15  
    16 using namespace std;
    17 typedef long long LL;
    18 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
    19 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
    20 inline int Max(int a,int b)    { return a>b?a:b; }
    21 inline int Min(int a,int b)    { return a>b?b:a; }
    22 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
    23 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
    24 const LL INF = 0x3f3f3f3f3f3f3f3f;
    25 const LL mod  = 1000000007;
    26 const double eps = 1e-8;
    27 const int inf  = 0x3f3f3f3f;
    28 const int maxk = 1e4+5;
    29 const int maxn = 1e5+10;
    30  
    31 struct edge2 {
    32     int x, y;
    33 }edge[100];
    34 int v, e1, e2;
    35 int g1[10][10], g2[10][10], num[10];
    36  
    37 void init()
    38 {
    39     memset(g1, 0, sizeof(g1));
    40     memset(g2, 0, sizeof(g2));
    41     for ( int i = 1; i <= v; i++ )
    42         num[i] = i;
    43  
    44     int x, y;
    45     for ( int i = 1; i <= e1; i++ )
    46         { scanf("%d %d", &x, &y); g1[x][y] = 1; g1[y][x] = 1; }
    47     for ( int i = 1; i <= e2; i++ )
    48     {
    49         scanf("%d %d", &x, &y);  g2[x][y] = 1; g2[y][x] = 1;
    50         edge[i].x = x;
    51         edge[i].y = y;
    52     }
    53  
    54 }
    55  
    56 int main()
    57 {
    58     while (~scanf("%d %d %d", &v, &e1, &e2))
    59     {
    60         init();
    61  
    62  
    63         set<long long> ss;
    64         do {
    65             int cnt = 0;
    66             long long has = 0;
    67             for (int i = 1; i <= e2; i++)
    68             {
    69                 if (g1[num[edge[i].x]][num[edge[i].y]])
    70                 {
    71                     has = has*177 + i;
    72                     has %= mod;
    73                     cnt++;
    74                 }
    75             }
    76  
    77             if (cnt == e1)
    78                 ss.insert(has);
    79  
    80         }while(next_permutation(num+1, num+1+v));
    81          
    82         printf("%zd
    ", ss.size());
    83     }
    84  
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    [斜率优化][DP]luogu P3648 序列分割
    [状压DP]luogu P1879 玉米田
    [最短路][期望DP]luogu P1850 换教室
    [DP]JZOJ 3046 游戏
    [组合数学]JZOJ 3013 填充棋盘
    [贪心]JZOJ 3012 购买
    [最大流][二分]JZOJ 1259 牛棚
    [数学][构造]JZOJ 3317 管道
    Cookie和Session
    XSS和CSRF的理解
  • 原文地址:https://www.cnblogs.com/chaoswr/p/9416624.html
Copyright © 2011-2022 走看看