好题
k=1做法:
直接倒着找,满足贪心性质,预处理出每个平方数就行.....
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<cstring> 10 #define MAXN 300001 11 #define int long long 12 #define ps push_back 13 using namespace std; 14 int a[MAXN]; 15 int n,K,kuan; 16 bool biao[MAXN]; 17 int ans[MAXN]; 18 int poww[MAXN]; 19 void work1() 20 { 21 int end=n; 22 while(end>0) 23 { 24 //printf("end=%lld ",end); 25 if(biao[a[end]]==1) 26 { 27 memset(biao,0,sizeof(biao)); 28 ans[++ans[0]]=end; 29 for(int i=2;i<=sqrt(kuan)+1;++i) 30 { 31 if(a[end]>poww[i])continue; 32 biao[poww[i]-a[end]]=1; 33 //printf("1::biao[%lld] ",poww[i]-a[end]); 34 } 35 end--; 36 } 37 else 38 { 39 for(int i=2;i<=sqrt(kuan)+1;++i) 40 { 41 if(a[end]>poww[i])continue; 42 biao[poww[i]-a[end]]=1; 43 //printf("biao[%lld] ",poww[i]-a[end]); 44 } 45 end--; 46 } 47 } 48 printf("%lld ",ans[0]+1); 49 if(ans[0]==0)printf(" "); 50 for(int i=ans[0];i>=1;--i) 51 { 52 printf("%lld ",ans[i]); 53 } 54 cout<<endl; 55 } 56 signed main() 57 { 58 //freopen("text.in","r",stdin); 59 //freopen("wa.out","w",stdout); 60 scanf("%lld%lld",&n,&K); 61 int maxn; 62 for(int i=1;i<=n;++i) 63 { 64 scanf("%lld",&a[i]); 65 maxn=max(maxn,a[i]); 66 } 67 kuan=maxn+maxn; 68 for(int i=2;i<=sqrt(kuan)+1;++i) 69 { 70 poww[i]=i*i; 71 } 72 if(K==1)work1(); 73 else printf("1 "); 74 } 75 /* 76 5 1 77 1 3 15 10 6 78 79 */
k=2做法:
其实这个我没打出正解并查集
用二分图强行卡常A了,把每个敌人和自己连边,染色判断
1 #include<bits/stdc++.h> 2 #include<iostream> 3 #include<cstdio> 4 #include<string> 5 #include<algorithm> 6 #include<cmath> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<cstring> 11 #define MAXN 1000001 12 #define ps push_back 13 using namespace std; 14 int a[MAXN]; 15 vector<int>v[650001]; 16 int n,K;bool tong[MAXN]; 17 bool biao[MAXN]; 18 int ans[MAXN]; 19 int poww[MAXN]; 20 int last[MAXN]; 21 void work1() 22 { 23 int p=n; 24 for(int i=n;i>=1;i--) 25 { 26 for(int j=512;j>=1;j--) 27 { 28 if(poww[j]<=a[i]) break; 29 if(last[poww[j]-a[i]]) 30 { 31 for(int k=p;k>i;k--) 32 last[a[k]]=0; 33 ans[++ans[0]]=i,p=i; 34 break; 35 } 36 } 37 last[a[i]]++; 38 } 39 printf("%d ",ans[0]+1); 40 for(int i=ans[0];i>=1;i--) 41 printf("%d ",ans[i]); 42 cout<<endl; 43 } 44 int col[MAXN]; 45 bool DFS(int x,int color,int r,int l,int fa) 46 { 47 col[x]=color; 48 for(int i=0;i<v[x].size();i++) 49 { 50 int to=v[x][i]; 51 if(to==fa||to>r||to<l)continue; 52 if(col[to]==0) 53 { 54 if(!DFS(to,3-color,r,l,x)) 55 return 0; 56 } 57 if(col[to]==col[x]) 58 { 59 return 0; 60 } 61 } 62 return 1; 63 } 64 signed main() 65 { 66 scanf("%d%d",&n,&K); 67 for(int i=1;i<=n;++i) 68 { 69 scanf("%d",&a[i]); 70 } 71 for(int i=1;i<=522;++i) 72 { 73 poww[i]=i*i; 74 tong[i*i]=1; 75 } 76 if(K==1)work1(); 77 else 78 { 79 int tail=n; 80 for(int end=n;end>=1;--end) 81 { 82 for(int i=tail;i>end;i--) 83 { 84 if(tong[a[i]+a[end]]) 85 { 86 v[i].ps(end);v[end].ps(i); 87 } 88 } 89 if(!DFS(end,1,tail,end,0)) 90 { 91 ans[0]++; 92 ans[ans[0]]=end; 93 tail=end; 94 v[end].clear(); 95 } 96 for(int i=tail;i>=end;i--) 97 { 98 col[i]=0; 99 } 100 } 101 printf("%d ",ans[0]+1); 102 if(ans[0]==0)cout<<endl; 103 for(int i=ans[0];i>=1;--i) 104 { 105 printf("%d ",ans[i]); 106 } 107 } 108 }