Educational Codeforces Round 67 (Rated for Div. 2)
https://codeforces.com/contest/1187
子数组交换,无法使小的数在大的数的右边
对于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\n"); 96 else 97 printf("NO\n"); 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\n",t); 29 // fprintf(out,"%d\n",t); 30 while (t--) 31 { 32 printf("%d\n",n); 33 // fprintf(out,"%d\n",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?'\n':' '); 42 // fprintf(out,"%d%c",a[i],i==n?'\n':' '); 43 for (i=1;i<=n;i++) 44 printf("%d%c",b[i],i==n?'\n':' '); 45 // fprintf(out,"%d%c",b[i],i==n?'\n':' '); 46 } 47 48 return 0; 49 }
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 }