牛客网暑期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\n", 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\n", ss.size());
83     }
84  
85     return 0;
86 }
View Code

 

posted @ 2018-08-03 22:29  LBNOQYX  阅读(224)  评论(0编辑  收藏  举报