Educational Codeforces Round 67 (Rated for Div. 2)

https://codeforces.com/contest/1187

D - Subarray Sorting 

子数组交换,无法使小的数在大的数的右边

对于b[i],第一个等于b[i]的数a[j] a数组1-j是否是a[j]最小,

if no, wrong

if yes, delete a[j]

其它的数并没有发生数值上的改变,只是位置变了,可以再次改变,且依然满足上述所说的‘无法使小的数在大的数的右边’

使用线段树

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <string>
  6 #include <algorithm>
  7 #include <iostream>
  8 using namespace std;
  9 #define ll long long
 10 
 11 const double eps=1e-8;
 12 const ll inf=1e9;
 13 const ll mod=1e9+7;
 14 const int maxn=3e5+10;
 15 
 16 int f[maxn<<2],first[maxn],last[maxn],nex[maxn],a[maxn],b[maxn];
 17 
 18 void build(int ind,int l,int r)
 19 {
 20     if (l==r)
 21         f[ind]=a[l];
 22     else
 23     {
 24         int m=(l+r)>>1;
 25         build(ind<<1,l,m);
 26         build(ind<<1|1,m+1,r);
 27         f[ind]=min(f[ind<<1],f[ind<<1|1]);
 28     }
 29 }
 30 
 31 void update(int ind,int l,int r,int x,int y)
 32 {
 33     if (l==r)
 34     {
 35         f[ind]=y;
 36         return;
 37     }
 38     int m=(l+r)>>1;
 39     if (x<=m)
 40         update(ind<<1,l,m,x,y);
 41     else
 42         update(ind<<1|1,m+1,r,x,y);
 43     f[ind]=min(f[ind<<1],f[ind<<1|1]);
 44 }
 45 
 46 int query(int ind,int l,int r,int y)
 47 {
 48     if (r<=y)
 49         return f[ind];
 50     int m=(l+r)>>1;
 51     if (m<y)
 52         return min(query(ind<<1,l,m,y),query(ind<<1|1,m+1,r,y));
 53     return query(ind<<1,l,m,y);
 54 }
 55 
 56 int main()
 57 {
 58     int t,n,i,v,d;
 59     scanf("%d",&t);
 60     while (t--)
 61     {
 62         scanf("%d",&n);
 63         for (i=1;i<=n;i++)
 64             scanf("%d",&a[i]);
 65         for (i=1;i<=n;i++)
 66             scanf("%d",&b[i]);
 67         memset(first,0,4*(n+1));
 68         memset(nex,0,4*(n+1));
 69         for (i=1;i<=n;i++)
 70         {
 71             if (first[a[i]]==0)
 72             {
 73                 first[a[i]]=i;
 74                 last[a[i]]=i;
 75             }
 76             else
 77             {
 78                 nex[last[a[i]]]=i;
 79                 last[a[i]]=i;
 80             }
 81         }
 82         build(1,1,n);
 83         for (i=1;i<=n;i++)
 84         {
 85             d=first[b[i]];
 86             first[b[i]]=nex[ first[b[i]] ];
 87             if (d==0)
 88                 break;
 89             v=query(1,1,n,d);
 90             if (v<b[i])
 91                 break;
 92             update(1,1,n,d,inf);
 93         }
 94         if (i==n+1)
 95             printf("YES
");
 96         else
 97             printf("NO
");
 98     }
 99     return 0;
100 }

别人大牛写的cdq分治,实在是看不懂:

https://codeforces.com/contest/1187/submission/56335528

code : build data (for hack)

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 #include <time.h>
11 
12 const double eps=1e-8;
13 const ll inf=1e9;
14 const ll mod=1e9+7;
15 const int maxn=3e5+10;
16 
17 int a[maxn],b[maxn];
18 
19 int main()
20 {
21 //    FILE *out=fopen("2.in","w");
22 //    srand(time(NULL));
23     int i;
24 //    int t=1,n=10;
25     int t=1,n=3e5;
26 //    int t=3e5,n=1;
27 //    int t=3e5/3,n=3;
28     printf("%d
",t);
29 //    fprintf(out,"%d
",t);
30     while (t--)
31     {
32         printf("%d
",n);
33 //        fprintf(out,"%d
",n);
34         for (i=1;i<=n;i++)
35         {
36 //            a[i]=rand()%n+1;
37             a[i]=rand()*6+100000;
38             b[i]=a[i];
39         }
40         for (i=1;i<=n;i++)
41             printf("%d%c",a[i],i==n?'
':' ');
42 //            fprintf(out,"%d%c",a[i],i==n?'
':' ');
43         for (i=1;i<=n;i++)
44             printf("%d%c",b[i],i==n?'
':' ');
45 //            fprintf(out,"%d%c",b[i],i==n?'
':' ');
46     }
47 
48     return 0;
49 }

 E - Tree Painting

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 
11 const double eps=1e-8;
12 const ll inf=1e9;
13 const ll mod=1e9+7;
14 const int maxn=2e5+10;
15 
16 struct node
17 {
18     int d;
19     node *to;
20 }*e[maxn];
21 
22 ll f[maxn],value[maxn],cnt[maxn];
23 int fa[maxn],n;
24 
25 ///just try to use dfs one time
26 void dfs(int d)
27 {
28     node *p=e[d];
29     int dd;
30     cnt[d]=1;
31     while (p)
32     {
33         dd=p->d;
34         if (fa[d]!=dd)
35         {
36             fa[dd]=d;
37             dfs(dd);
38             cnt[d]+=cnt[dd];
39             value[d]+=value[dd];
40             f[d]=max(f[d],f[dd]-cnt[dd]-value[dd]);
41         }
42         p=p->to;
43     }
44     value[d]+=cnt[d];
45     f[d]+=n+value[d]-cnt[d];
46 }
47 
48 int main()
49 {
50     node *p;
51     int i,x,y;
52     scanf("%d",&n);
53     for (i=1;i<n;i++)
54     {
55         scanf("%d%d",&x,&y);
56         p=new node();
57         p->d=y;
58         p->to=e[x];
59         e[x]=p;
60 
61         p=new node();
62         p->d=x;
63         p->to=e[y];
64         e[y]=p;
65     }
66     dfs(1);
67     printf("%lld",f[1]);
68     return 0;
69 }
原文地址:https://www.cnblogs.com/cmyg/p/11116892.html